給定一個陣列 nums,定義**執行和(Running Sum)**為 runningSum[i] = nums[0] + nums[1] + ... + nums[i]。
請回傳 nums 的執行和陣列。換言之,輸出陣列的第 i 個元素等於輸入陣列前 i+1 個元素的總和。
範例:
nums = [1, 2, 3, 4][1, 3, 6, 10]這道題是前綴和最基礎、最直觀的形式。對於每個位置 i(從 1 開始),只需將前一個位置的值加到當前位置:
nums[i] += nums[i-1]
這樣 nums[i] 就從「原始值」變成「前 i+1 個元素的總和」,正好是所求的執行和。
為什麼能原地計算? 因為計算 nums[i] 時,只依賴 nums[i-1](已經是前 i 個元素的和),不需要之前更早的資訊。從左到右依序計算,每個位置只讀取一次前一個位置的值,沒有資料相依問題。
標準前綴和通常定義 prefix[i] = nums[0] + ... + nums[i-1](從 0 開始,長度為 n+1),而本題的執行和等同於「在原陣列上做 in-place 前綴和」,即 result[i] = nums[0] + ... + nums[i](從 0 開始,長度為 n)。
兩者本質相同,只是索引偏移不同。理解這道題是掌握所有前綴和題目的起點。
O(n),其中 n 為陣列長度。只需從頭到尾遍歷一次陣列,每個元素執行一次加法運算。
若題目允許修改輸入陣列,原地版本是最佳選擇;若需保留原始陣列,則使用新陣列版本。
1. For i from 1 to n-1: a. nums[i] = nums[i] + nums[i-1] 2. Return nums (Alternative with new array): 1. Create result array of size n 2. result[0] = nums[0] 3. For i from 1 to n-1: a. result[i] = result[i-1] + nums[i] 4. Return result
partial_sum(STL 標準庫)C++ STL 提供了 std::partial_sum 函式(定義於 <numeric>),可以直接計算前綴和:partial_sum(nums.begin(), nums.end(), result.begin())。
將執行和定義為遞迴:runningSum(i) = runningSum(i-1) + nums[i],以遞迴方式實作。
使用函式式程式設計中的 scan 操作(類似 reduce 但保留所有中間結果),概念上與前綴和完全等價。Python 的 itertools.accumulate、Haskell 的 scanl1 都是此思路。
partial_sum,不如迴圈直觀。區間和查詢:若在建立執行和之後,需要大量回答「nums[left] 到 nums[right] 的總和是多少」,執行和陣列如何幫助我們 O(1) 回答?(sumRange(l, r) = runningSum[r] - runningSum[l-1],當 l > 0 時;注意 l=0 的邊界。)
二維執行和:如何將此概念推廣到二維矩陣,計算每個 (i, j) 點的「左上角矩形和」?這就是二維前綴和,用於 O(1) 回答任意子矩陣查詢(LC 304)。
差分陣列是前綴和的逆操作:執行和(前綴和)是累積加法,而差分陣列是它的逆——diff[i] = nums[i] - nums[i-1]。對差分陣列做前綴和還原就能得到原始陣列。這個性質可用於高效率地對陣列區間進行批量加減操作(LC 370)。