
Waymo 的面試題很常有一種很典型的風格:題面看起來不複雜,但如果你一開始順著直覺走,很容易掉進一個「局部看起來合理、全域其實不穩」的坑裡。
這道題就是這種類型。
如果把它改成更貼近自動駕駛場景的說法,可以這樣理解:
系統正在監控一段目標道路,範圍是一個閉區間 [roadStart, roadEnd]。
同時會按時間順序收到一批「路段觀測片段」,每個片段也是一個閉區間 [segmentStart, segmentEnd]。
這些片段會一個一個到來,順序固定,不能重排。
問題是:
第幾個片段到來之後,這些已到達片段在目標道路上的聯合集合,第一次把整段目標路完全覆蓋?
如果到最後都沒能完整覆蓋,就回傳 -1。
這題最容易讓人誤判的地方
很多人的第一反應會是:
- 每來一個新區間
- 就把所有區間重新 merge 一次
- 然後檢查能不能覆蓋整段目標區間
這個方向當然可以做,但一旦區間數量變大,重複全量 merge 的複雜度會非常難看。
所以面試裡很容易立刻被追問一句:
能不能比「每次把所有區間重新合併一次」做得更好?
而這裡最關鍵的一點,其實不是區間 merge 本身,而是:
輸入順序固定,不能排序。
這一點會直接殺死很多「我先排個序再掃一遍」的自然想法。
先別急著寫程式,這題最值得先確認的邊界
這道題特別適合先做幾句 clarify,因為這些細節會直接影響後面的合併規則。
比較關鍵的點通常包括:
- 區間是不是閉區間
- 座標會不會有負數
- 單個片段能不能完全落在目標道路之外
而這題裡最關鍵的資訊通常是:
片段可以超出目標道路,真正有意義的只有它和目標區間的交集。
也就是說,你不需要關心區間在目標區間外面的那一部分。
每次真正參與覆蓋判斷的,只是它對 [roadStart, roadEnd] 的有效貢獻。
這個點一旦想清楚,後面的狀態空間會小很多。
為什麼「維護目前能延伸到哪裡」這個貪心不夠穩
有些候選人會想到一種更輕量的做法:
- 維護一個目前已經連續覆蓋到的位置
- 如果新片段能接上,就往右延
- 一旦覆蓋到終點,就回傳
這個想法在很多順序漂亮的測試裡會過,但它有一個根本問題:
它隱含假設了對你有幫助的區間會按照「可延伸」的順序到來。
可現實裡輸入順序是固定但可能很亂。
例如:
- 目標區間是
[0, 100] - 到來的片段依序是
[50, 60]、[0, 10]、[10, 50]
如果你只盯著「目前連續覆蓋能不能往右推」,第一個區間看起來沒辦法從左端接上,第二個只能到 10,直到第三個才突然閉合。
這說明了什麼?
說明你不能只維護一個「目前最遠右邊界」,因為:
- 有些早到的片段雖然當下接不上
- 但它們會在未來和後來的片段拼起來
- 最後共同形成完整覆蓋
所以這題不能被簡化成單一右邊界貪心。
正確建模:維護「目前已形成的若干段不相交覆蓋區間」
更穩的思路是把問題看成一個 online 版的動態區間合併。
每來一個新區間,只做兩件事:
- 先把它裁剪到目標道路內部
- 再把它和目前已經維護的覆蓋區間集合合併
這裡維護的不是所有歷史原始區間,而是:
目前在目標道路上已經形成的、不相交的覆蓋區間集合
這樣做的好處是:
- 你不會丟掉那些「現在還接不到左端、但未來可能拼起來」的片段
- 你也不需要每次重新 merge 全部原始輸入
你真正維護的是「合併後的狀態」,而不是「原始歷史」。
為什麼要先裁剪到目標區間
這一步很容易被帶過,但其實非常值得主動講出來。
如果一個新片段是:
- 完全在目標區間外
- 或者只部分和目標區間相交
那它真正對答案有用的,只有和目標區間的交集。
所以每次新片段到來時,可以先做:
- 左邊界取
max(segmentStart, roadStart) - 右邊界取
min(segmentEnd, roadEnd)
如果裁完之後左邊大於右邊,那就代表這個片段對目標道路沒有任何貢獻,可以直接忽略。
這一層處理能讓後面所有邏輯都只圍繞目標區間內部展開,表達會清晰很多。
動態區間合併的核心思路
假設目前已經維護了一組按起點排序、彼此不重疊的覆蓋區間。
當一個新的有效片段進來時,你需要做的是:
- 找到它左邊可能和它相交或相接的區間
- 繼續向右吸收所有和它重疊或接觸的區間
- 合併成一個更大的新區間
- 再把這個新區間放回結構裡
因為區間是閉區間,所以像:
[0, 10][10, 20]
這種在端點處相接的情況,也應該視為已經連通,不需要再拆開。
所以合併條件不是「嚴格重疊」,而是「重疊或接觸」。
這也是這題比普通離線 merge intervals 更像工程題的地方:你需要在線地維護合併後的狀態。
什麼時候可以回傳答案
這題問的是:
第幾個片段出現後,目標區間第一次被完整覆蓋。
所以在每次插入並完成合併後,只需要檢查:
- 是否存在一個覆蓋區間,它的左端點已經小於等於
roadStart - 並且它的右端點已經大於等於
roadEnd
一旦成立,就代表目標區間第一次被完整蓋住,當前片段編號就是答案。
這裡不需要再去算「總覆蓋長度」。
因為總長度就算剛好夠,也可能中間還有縫。
真正可靠的判斷是:是否已經形成了一個能完整跨過目標區間的連續合併段。
這題為什麼比「每次全量 merge」更優
如果你每來一個新區間都對所有歷史區間重新排序並 merge,代價會非常高。
而如果你維護的是:
- 已經合併好的不相交區間集合
那每次新片段到來時,真正需要處理的只是:
- 和它局部相鄰的那幾段
這使得整體複雜度更可控,也更符合 online processing 的語義。
一個比較自然的實作載體通常是:
- 有序映射
- 平衡樹
- 或任何支援按起點查找相鄰區間的資料結構
面試裡不一定非要寫出最重的工程實作,但一定要把這個狀態維護思路講清楚。
面試裡可能繼續追問的幾個方向
Follow-up 1:如果輸入規模到百萬級怎麼辦?
這類問題通常是在問:
- 你現在是不是還在做全量重算
如果你已經切到「維護合併後區間集合」的思路,這時就可以很自然地回答:
- 仍然是 online 處理
- 不做全量重 merge
- 每個新區間只和局部相鄰覆蓋段發生關係
Follow-up 2:如果允許重排所有片段呢?
這時問題就會立刻退化成經典的區間覆蓋問題。
一旦允許排序,就可以:
- 先按起點排序
- 再用標準貪心檢查是否能從左到右完整覆蓋目標區間
複雜度自然會走向 O(n log n)。
Follow-up 3:如果從一維變成二維呢?
這也是非常典型的壓軸追問。
一旦覆蓋對象從線段變成矩形,問題就不再是簡單區間合併了,複雜度會明顯上升。
這時一個比較合理的延伸方向通常是:
- sweep line
- segment tree
也就是把二維覆蓋問題拆成一維掃描 + 動態維護。
不需要真的把二維完整寫出來,但要體現你知道為什麼一維思路不能直接原封不動搬過去。
這題在 Waymo 面試裡真正考察的是什麼
這題表面是區間題,但它更像是在看你有沒有在線維護狀態的能力。
真正的考點不是:
- 你會不會 merge intervals
而是:
- 你能不能意識到順序固定,不能排序
- 你能不能避免每次全量重算
- 你能不能把問題抽象成「維護合併後的有效狀態」
這也是 Waymo 這類題很常見的特點:
- 背景看起來業務化
- 第一眼直覺很容易錯
- 真正正解通常來自更穩的狀態維護
所以這題並不是在比誰刷題多,而是在比誰更快意識到「這不是靜態區間題,而是 online 覆蓋問題」。
📌 最後總結
這道題最值得記住的,不是「第幾個片段把地面蓋住」這種表層敘述,而是它背後的結構:
- 輸入順序固定
- 不能排序
- 但又要動態判斷是否已形成完整覆蓋
一旦抓住這一點,最穩的解法就不是單一右邊界貪心,而是:
- 每次先裁剪區間到目標區間
- 再動態合併到目前覆蓋區間集合中
- 最後判斷是否已經形成完整跨越目標區間的一段
如果你最近在準備 Waymo 或類似風格的 VO,這類「在線維護區間狀態」的題非常值得專門練。因為它特別容易暴露一個人到底是在套模板,還是在真正理解問題結構。
🚀 oavoservice:你的 Waymo VO 穩定輸出保障
如果你最近有 Waymo、Google、Apple、LinkedIn、Amazon 這類 VO 面試,提前準備這些真實題型和 follow-up 思路會非常關鍵。
我們提供:
✅ 大廠 VO 即時輔助 — Coding、BQ、System Design 全程支持
✅ 真實題型 mock — 盡可能還原實際面試節奏
✅ 高壓 follow-up 訓練 — 不只練第一問,更練追問下的穩定輸出
✅ 長題建模訓練 — 幫你把業務背景快速翻譯成可解的結構
如果你想提前感受最接近實戰的 feedback,也歡迎直接來聊。
👉 立即添加微信:Coding0201
Telegram: @OAVOProxy
Gmail: [email protected]