題目描述:給定一個字串陣列 words,其中有一個隱藏的秘密單字。你可以呼叫 guess(word) API,它會回傳你猜測的單字與秘密單字之間完全匹配(位置和字元都相同)的字元數。若回傳 6 表示猜中。目標是在 10 次猜測以內找到秘密單字。
解題思路:這是一道互動式問題,核心是每次猜測後應最大限度地縮減候選集合。
關鍵觀察:若 guess(w) 回傳 k,則秘密單字與 w 恰好有 k 個位置字元相同。因此我們可以把候選集縮減為「與 w 的 match 數恰好等於 k」的所有單字。
Minimax 策略:對每個候選單字 w,計算以 w 猜測後的最壞情況(即剩餘候選數最多的那個 match bucket 的大小)。選能最小化最壞情況候選數的單字來猜。但由於總候選只有 ≤100 個且時間有限,也可採用更簡潔的隨機策略:每次隨機從候選集選一個猜,根據 match 數過濾候選集;數學上期望約 6.5 次即可收斂,10 次限制在大多數情況下足夠。
Match 計算輔助函數:給定兩個長度為 6 的字串,計算有幾個位置字元完全相同(即 exact match 數)。
時間複雜度:O(N² × L) — 每次猜測,對每個候選單字(最多 N 個)都要遍歷所有候選計算 match 數(N 次,每次 O(L),L=6);最多進行 10 次猜測,共 O(10 × N² × L)。N ≤ 100,L = 6,實際上非常快。
空間複雜度:O(N) — 儲存候選集合,最多 N 個字串。
1. Initialize candidates = all words in the word list
2. Repeat up to 10 times (while candidates is not empty):
a. For each candidate word w, compute its worst-case remaining size:
- For each possible match count k in [0..5], count how many candidates have exactly k matches with w
- worst_case(w) = max count among buckets k=0..5
b. Pick 'best' = the word w with the smallest worst_case value
c. Call result = master.guess(best)
d. If result == 6, return (secret found)
e. Filter candidates: keep only words c where countMatches(best, c) == result
3. End (should have found answer within 10 guesses)方法一:隨機猜測法(Random Candidate Selection) 每次從候選集中隨機選一個單字猜,根據 match 數過濾候選集。時間複雜度 O(N × L) per round,實作極為簡單。由於候選集平均每次會縮減至約 1/6,期望約 3–4 輪即可收斂。但最壞情況下可能失敗(超過 10 次),在面試中需說明這一點。
方法二:零 Match 優先過濾(Zero-Match Filter Heuristic) 針對候選集中 match=0 最少的單字優先猜。統計每個單字在所有候選對中產生 match=0 的比例,優先猜「與其他候選最不相似」的字。這能更積極地分割候選集,但計算量仍為 O(N²),精確度介於純隨機與完整 minimax 之間。
方法三:DP/資訊熵最大化(Max Information Gain) 選擇使猜測結果的資訊熵最大化的字(類似 Wordle 最優策略)。計算每個字的猜測結果分布,選熵最高者,理論上最優但計算量更大,對本題(N≤100)實際上與 minimax 相差無幾。