給定長度為 n 的陣列(初始值全為 0),以及 k 個更新操作,每個操作為 [startIndex, endIndex, inc],代表將陣列索引 [startIndex, endIndex] 的所有元素都加上 inc。
完成所有操作後,回傳最終陣列。
範例:n=5, operations = [[1,3,2],[2,4,3],[0,2,-2]]
暴力解法是對每個操作遍歷 [startIndex, endIndex] 並逐一更新,時間複雜度 O(n × k),效率低。
差分陣列是處理「區間批量修改」的經典技巧,時間複雜度降至 O(n + k):
定義差分陣列 diff[i] = result[i] - result[i-1](result[-1] = 0)。對區間 [l, r] 加 val 等價於:
diff[l] += val(從 l 開始增加)diff[r+1] -= val(在 r+1 處撤銷增加)最後對差分陣列做前綴和還原,即可得到最終結果:
result[i] = diff[0] + diff[1] + ... + diff[i]
每個操作只修改兩個位置(O(1)),而不是整個區間(O(n))。k 個操作後,前綴和一次性還原所有修改。
直觀理解:diff[l] += val 代表「從 l 開始,後綴全部加 val」,diff[r+1] -= val 代表「從 r+1 開始,後綴全部減 val」,兩者疊加效果恰好是「區間 [l,r] 加 val」。
O(n + k),其中 n 為陣列長度,k 為操作次數。
O(n),需要差分陣列(或直接在結果陣列上操作)。不計算輸出陣列本身的話,額外空間為 O(1)(原地版本)。
1. Initialize diff array of size (n+1) to all zeros 2. For each update [l, r, val]: a. diff[l] += val b. diff[r+1] -= val 3. Initialize result array of size n 4. Set running = 0 5. For i from 0 to n-1: a. running += diff[i] b. result[i] = running 6. Return result
對每個操作 [l, r, val],用迴圈將 result[l] 到 result[r] 都加上 val。
使用帶懶惰標記的線段樹,支援 O(log n) 的區間更新和 O(log n) 的點查詢。
支援區間加法和前綴和查詢,利用兩個 BIT 可以實作 O(log n) 的區間修改和 O(log n) 的單點查詢。
二維差分陣列:若問題從一維推廣到二維——對矩形子矩陣批量加值,如何設計差分陣列?定義 diff[i][j] 的二維差分,對矩形 (r1,c1) 到 (r2,c2) 加 val:diff[r1][c1] += val, diff[r1][c2+1] -= val, diff[r2+1][c1] -= val, diff[r2+1][c2+1] += val;最後做二維前綴和還原。
線上查詢(online query):本題中所有操作批量完成再查詢。若需要在每次操作後立即查詢某位置的值,差分陣列無法直接支援,應改用線段樹(Lazy Propagation)或樹狀陣列(BIT)的區間加點查詢模式。
差分陣列與前綴和的對偶關係:前綴和的逆操作是差分(diff[i] = arr[i] - arr[i-1]),對差分陣列做前綴和可還原原陣列。理解這個對偶關係有助於解決 LC 1094(Car Pooling)、LC 1109(Corporate Flight Bookings)等時間序列資源分配問題。