LeetCode 🟡 3964. Minimum Lights to Illuminate a Road
🔗 🟡 3964. Minimum Lights to Illuminate a Road
Problem Statement
題目簡述
給定一個長度為 的陣列 lights,代表道路上位置 到 的初始燈泡狀態:
- 若
lights[i] = v > 0,表示位置 有一個工作的燈泡,可以照亮 範圍內的所有位置。 - 若
lights[i] = 0,表示該位置沒有工作燈泡。
我們可以安裝額外的燈泡,每個額外燈泡安裝在位置 可以照亮 範圍內的所有位置。
求最少需要安裝多少個額外燈泡,才能使整條道路的每個位置都被照亮。
Constraints
約束條件
思路:差分陣列 + 貪心
1. 題型定位:區間覆蓋
本題本質是區間覆蓋問題:給定一些初始區間(工作燈泡的覆蓋範圍),求最少需要添加多少個固定長度的新區間(半徑為 的額外燈泡),才能完整覆蓋整條線段。
題型總結
差分陣列維護區間覆蓋狀態 + 從左到右遇缺即補的貪心模型,在路燈安置、灌溉覆蓋、基地台選址等場景反覆出現,是區間覆蓋類問題的核心套路。
2. 從暴力出發:為什麼需要差分陣列?
最直接的想法:對於每個初始燈泡,遍歷其覆蓋區間內的所有位置並標記為「已照亮」。但每個燈泡的覆蓋半徑可能高達 ,總複雜度 ,在 下顯然不可行。
標記「哪些位置被照亮」本質上是在做「區間加值」。有沒有比逐個位置修改更快的方法?
答案是差分陣列:對 區間加 ,只需在 處 、 處 ,最後一次前綴和掃描即可還原每個位置的實際值。
前置知識:差分陣列
差分陣列是維護「區間修改、單點查詢」的經典工具。
對於區間 的加 操作,只需要在差分陣列中令 位置 且 位置 。
最後對差分陣列求前綴和,即可在 時間內得到每個位置的最終值。
初始化時,對每個工作燈泡,將其覆蓋區間用差分陣列標記 ,然後做一次前綴和還原,就能知道每個位置被初始燈泡覆蓋了幾次。
3. 貪心決策:遇缺即補,燈泡靠右放
現在有了每個位置的覆蓋次數,從左到右掃描:
- 若當前位置已被覆蓋(次數 ):繼續前進。
- 若當前位置未被覆蓋(次數 ):必須放置一個額外燈泡。
關鍵觀察:燈泡放哪最優?
額外燈泡的半徑為 ,要覆蓋當前未被照亮的位置,燈泡可以放在 中的任何位置。但為了最大化對後續位置的貢獻,應該放在最右側,即 ,這樣它的覆蓋區間是 ,能順便照亮後續兩個位置。
在差分陣列上的操作體現為:放置新燈泡後,將當前位置的覆蓋次數加 ,並在該燈泡覆蓋結束的下一個位置(即 )處減 ,表示它的覆蓋到此結束。
複雜度分析
- 時間複雜度:,初始化差分陣列與一次線性掃描各
- 空間複雜度:,差分陣列需要 的輔助空間
Code
1 | class Solution: |
本部落格所有文章除特別聲明外,均採用CC BY-NC-SA 4.0 授權協議。轉載請註明來源 十六個天亮!
評論
WalineGiscus





![Luogu 🟣 P3195 [HNOI2008] 玩具装箱](https://i.gdst.dev/cover/P3195.webp)