← 返回博客列表
Microsoft

🚨 Microsoft 2026 Codility OA 真题流出!110 分钟 2 道题,为何看似简单却挂了一大片?

2026-01-24

最近,Microsoft 的 Codility OA 正在大量發放中。

很多同學看到題目後的第一反應是:「穩了,這不就是 DP/貪心 嗎?」

千萬別大意。

如果你只把它當成普通的演算法題寫,哪怕 Bug Free,大概率也只能拿個 Rej。

我們 oavoservice 團隊第一時間拿到了真題,發現這裡面埋了無數個 Engineering Judgment(工程判斷力) 的深坑。

🔍 為什麼 Microsoft Codility 的題「陰」?

Microsoft 不像 Google/Meta 那樣喜歡出 LeetCode Hard,但它有個更噁心的特點:

題目描述很長,業務場景複雜
需要自己處理輸入輸出
邊界條件極其刁鑽
DP 狀態定義稍有偏差,全盤皆輸

而且 Codility 平台的特點是:

這種「盲打」模式,對心態的考驗極大。

昨天我們有個 UIUC 的學員,第一題寫了 40 分鐘,提交後發現只過了 60%,當場就慌了。如果不是我們的 Senior 導師實時在語音裡穩住他:「別急,這是 DP 狀態轉移出了問題,重新定義狀態!」,他大概率第二題都寫不完。

最後結果?110分鐘,2道題,全部 All Passed。 穩穩拿下面試門票。

今天把這套熱乎的真題拆解一下,告訴你們坑都在哪。

💻 真題一:多米諾骨牌序列(Domino Sequence)

🔍 題目核心

給定長度為 2*N 的陣列 A,表示 N 個多米諾骨牌。每個骨牌由兩個數字組成:

正確的多米諾序列:相鄰骨牌的接觸部分數字必須相同。

題目要求:最少需要移除多少個骨牌,使剩餘骨牌形成正確序列?

限制

範例解析

Example 1:

A = [2, 4, 1, 3, 4, 6, 2, 4, 1, 6]
骨牌:(2,4), (1,3), (4,6), (2,4), (1,6)

答案:3

🤯 為什麼這題掛了一大片?

絕大多數人看到這題,第一反應是:

❌ 「這不就是最長連續子序列嗎?」
❌ 「用貪心,能連就連!」
❌ 「暴力列舉所有可能!」

然後越寫越亂,最後發現根本處理不了:

  1. 如何定義「可連接」?
  2. 如何處理多個可能的起點?
  3. 如何保證找到全域最優解?

✅ 正確的工程思維

這是一個**「最長遞增子序列」的變種 + DP」**問題。

關鍵洞察

這不是「貪心」,而是「動態規劃」!

💣 隱形坑點

坑點 1:陣列索引轉換

# 錯誤寫法
left = A[i]  # ❌ 這是什麼?

# 正確寫法
left = A[2*i]      # 第 i 個骨牌的左邊
right = A[2*i + 1]  # 第 i 個骨牌的右邊

坑點 2:邊界條件

坑點 3:DP 初始化

🎯 滿分實作(Python)

def solution(A):
    if len(A) == 0:
        return 0
    
    n = len(A) // 2
    if n == 1:
        return 0
    
    # 構建骨牌列表
    dominoes = []
    for i in range(n):
        left = A[2 * i]
        right = A[2 * i + 1]
        dominoes.append((left, right))
    
    # DP: dp[i] 表示以第 i 個骨牌結尾的最長序列長度
    dp = [1] * n
    
    for i in range(1, n):
        for j in range(i):
            # 如果第 j 個骨牌的右邊等於第 i 個骨牌的左邊
            if dominoes[j][1] == dominoes[i][0]:
                dp[i] = max(dp[i], dp[j] + 1)
    
    # 最長序列的長度
    max_keep = max(dp)
    
    # 需要移除的數量
    return n - max_keep

⚡️ 時間複雜度優化

上面的解法是 O(n²),對於 N=50,000 可能會 TLE。

優化思路:用 HashMap 記錄每個右值對應的最長序列

def solution(A):
    if len(A) == 0:
        return 0
    
    n = len(A) // 2
    if n == 1:
        return 0
    
    # HashMap: right_value -> max_length
    max_len = {}
    overall_max = 1
    
    for i in range(n):
        left = A[2 * i]
        right = A[2 * i + 1]
        
        # 查找能連接到當前骨牌左邊的最長序列
        current_len = max_len.get(left, 0) + 1
        
        # 更新以 right 結尾的最長序列
        max_len[right] = max(max_len.get(right, 0), current_len)
        
        overall_max = max(overall_max, current_len)
    
    return n - overall_max

時間複雜度:O(n)
空間複雜度:O(1) (因為骨牌數字只有 1-6)

🔢 真題二:三個非相鄰元素的最大和(Maximum Sum of Three Non-Adjacent Elements)

🔍 題目核心

給定整數陣列 A,選擇恰好 3 個非相鄰元素,使其和最大。

非相鄰定義:三個元素的索引必須滿足任意兩個索引的差 > 1。

限制

範例解析

Example 1:

A = [8, -4, -7, -5, -5, -4, 8, 8]

答案:12

Example 2:

A = [-2, -8, 1, 5, -8, 4, 7, 6]

答案:15

Example 3(負數情況):

A = [-3, 0, -6, -7, -9, -5, -2, -6]

答案:-9

🤯 隱形殺招:為什麼 90% 的人會掛?

看似簡單的題目,實際上有三個致命陷阱

陷阱 1:暴力列舉會 TLE

# ❌ 這樣寫必掛
max_sum = float('-inf')
for i in range(n):
    for j in range(i+2, n):
        for k in range(j+2, n):
            max_sum = max(max_sum, A[i] + A[j] + A[k])

時間複雜度:O(n³),對於 N=100,000 必然超時

陷阱 2:貪心選 3 個最大值會錯

# ❌ 錯誤思路
sorted_indices = sorted(range(n), key=lambda i: A[i], reverse=True)
# 然後試圖找 3 個不相鄰的?

反例:

A = [10, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 1, 8]

貪心在有負數時完全失效!

陷阱 3:DP 狀態定義不清晰

很多人想用 DP,但不知道狀態怎麼定義:

# ❌ 錯誤狀態
dp[i] = "前 i 個元素的最大和"  # 選了幾個?

✅ 正確的工程思維:枚舉中間元素 + 預處理

核心洞察

固定中間元素,問題變簡單!

  1. 枚舉第二個元素的位置 j(中間那個)
  2. [0, j-2] 中找最大值(第一個元素)
  3. [j+2, n-1] 中找最大值(第三個元素)

關鍵優化:預處理前綴/後綴最大值

💣 最容易翻車的地方

邊界條件:

負數處理:

🎯 滿分實作(Python)

def solution(A):
    n = len(A)
    
    # 邊界檢查
    if n < 5:
        return float('-inf')  # 不可能有解
    
    # 預處理:prefix_max[i] 表示 [0, i] 的最大值
    prefix_max = [float('-inf')] * n
    prefix_max[0] = A[0]
    for i in range(1, n):
        prefix_max[i] = max(prefix_max[i-1], A[i])
    
    # 預處理:suffix_max[i] 表示 [i, n-1] 的最大值
    suffix_max = [float('-inf')] * n
    suffix_max[n-1] = A[n-1]
    for i in range(n-2, -1, -1):
        suffix_max[i] = max(suffix_max[i+1], A[i])
    
    # 枚舉中間元素
    max_sum = float('-inf')
    for j in range(2, n-2):
        # 第一個元素從 [0, j-2] 中選
        first = prefix_max[j-2]
        # 第三個元素從 [j+2, n-1] 中選
        third = suffix_max[j+2]
        
        current_sum = first + A[j] + third
        max_sum = max(max_sum, current_sum)
    
    return max_sum

時間複雜度:O(n)
空間複雜度:O(n)

💡 說句現實的:Microsoft Codility OA,真的不適合裸考

Microsoft SDE 的 TC(北美):

New Grad:$160k – $180k
SDE II:$200k – $250k

而 Codility OA 的殘酷現實是:

輸入輸出需要自己處理
沒有互動式除錯
一個邊界條件錯誤 = 全掛
一次機會,可能等半年

我們在 oavoservice 做的事情,其實很簡單:

你寫程式碼
有人盯狀態定義
有人盯邊界條件
有人盯時間複雜度
在你要 TLE / 寫歪之前,直接叫停

不是你不行,是一個人上場風險太高。

🚀 oavoservice:你的滿分通關專家

面對 Microsoft 這種 工程量大、細節層層遞進 的 Codility OA,你需要的不只是一份答案,而是一個專業的 技術團隊 支援。

我們提供:

Codility 平台全覆蓋:熟悉平台特性,規避隱藏陷阱
程式碼符合工業級標準:Production-Level Code,不是刷題風格
實時語音助攻:OA 進行時,資深工程師實時指導
滿分保障:不過不收費,我們對自己的實力有信心

不要讓一道 DP 狀態轉移、一個邊界條件,卡住你通往 $200k Offer 的路。

我們長期穩定承接各大科技公司如 Microsoft、Google、Amazon 等的 OA 筆試代寫服務,確保滿分通過。

👉 立即添加微信:Coding0201

鎖定你的 Microsoft 面試機會!