➕用Python來實現 Prefix sum 前綴和

更新於 發佈於 閱讀時間約 1 分鐘

定義

Prefix Sum(前綴和)是一種用於計算陣列中任意區間和的高效方法

前綴和算是一種犧牲空間換取時間效能提升的策略。
這在需要頻繁查詢區間和的情況下特別有用。


一開始,初始化時花費O(n)時間,掃描每個元素累加,建立一個prefix sum table
接著,提供query介面,提供使用者查詢任意的區間和,並且能夠在O(1)得到答案


示意圖

raw-image

優點

1.提升區間和查詢效能,可以在O(1)時間內計算並且得到任意區間和。


缺點

1.需要額外花費O(n)空間來建立prefix sum table。

2.事前需要花費O(n)時間掃描每個陣列元素累加,建立prefix sum table。


Prefix Sum的class定義 與 初始化

class PrefixSum:
def __init__(self, arr):

# 建構子
self.prefix_sums = self._compute_prefix_sums(arr)

def _compute_prefix_sums(self, arr):

# 事先花費O(n)時間計算前綴和
prefix_sums = [0 for _ in range(len(arr)) ]

prefix_sums[0] = arr[0]

for i in range(1, len(arr)):
prefix_sums[i] = prefix_sums[i - 1] + arr[i]

return prefix_sums

Prefix Sum常見的操作


1.查詢區間和 range_sum(left, right)


如果left 是零,代表左邊端點是起點,直接返回self.prefix_sums[right]即可。

如果left非零,利用區間和抵銷的觀念,計算

self.prefix_sums[right] - self.prefix_sums[left-1] 得到區間和。


時間複雜度: O(1)

    def range_sum(self, left, right):

if left == 0:
return self.prefix_sums[right]

else:
return self.prefix_sums[right] - self.prefix_sums[left-1]

測試範例

raw-image

完整的Prefix sum實作和程式碼

class PrefixSum:
def __init__(self, arr):
self.prefix_sums = self._compute_prefix_sums(arr)

def _compute_prefix_sums(self, arr):
prefix_sums = [0 for _ in range(len(arr)) ]

prefix_sums[0] = arr[0]

for i in range(1, len(arr)):
prefix_sums[i] = prefix_sums[i - 1] + arr[i]

return prefix_sums

def range_sum(self, left, right):

if left == 0:
return self.prefix_sums[right]

else:
return self.prefix_sums[right] - self.prefix_sums[left-1]

def test():
# Demo
arr = [3, 4, 1, 7, 9, 1]
prefix_sum = PrefixSum(arr)
print("Input array :", arr)
print("Prefix sum :", prefix_sum.prefix_sums)
print("\nSum of range (1, 3):", prefix_sum.range_sum(1, 3))
print("Sum of range (0, 5):", prefix_sum.range_sum(0, 5))


if __name__ == '__main__':
test()

測試輸出

Input array : [3, 4, 1, 7, 9, 1]
Prefix sum : [3, 7, 8, 15, 24, 25]

Sum of range (1, 3): 12
Sum of range (0, 5): 25

結語


其實前綴和就是陣列元素的累加,而區間和就是區間元素的累加
透過事前額外的計算建表,提升run-time 區間和的查詢與計算效能


讀者可以透過紙筆追蹤演算法和程式執行邏輯,測試幾個簡單的小範例,

會有更深刻的了解和體會!


Prefix sum相關的演算法練習題與詳解


前綴和應用: 指定目標值的子陣列數目 Binary Subarrays With Sum_Leetcode #930


前綴和應用: 總和=k的子陣列有幾個 Subarray Sum Equals K_Leetcode #560


合縱連橫: 從區間和應用理解 前綴和 的本質


前綴和應用: 尋找旅途中的海拔最高點_Leetcode #1732 精選75題解析

留言
avatar-img
留言分享你的想法!
小松鼠-avatar-img
發文者
2024/09/02
林燃(創作小說家) 剛剛吃了一塊小麵包 哈哈
小松鼠-avatar-img
發文者
2024/09/03
動手學Python/資料結構/演算法 的目錄提及了這篇文章,趕快過去看看吧!
avatar-img
小松鼠的演算法樂園
95會員
427內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
2024/10/10
從Python 內建deque資料結構的角度切入, 同時了解deque 與 FIFO Queue相關的function用法。 collections.deque是一種兩端點皆可進出的雙端佇列 在兩端點高效地在O(1)常數時間內添加和刪除元素。 這使得deque非常適合實現FIFO Queue
Thumbnail
2024/10/10
從Python 內建deque資料結構的角度切入, 同時了解deque 與 FIFO Queue相關的function用法。 collections.deque是一種兩端點皆可進出的雙端佇列 在兩端點高效地在O(1)常數時間內添加和刪除元素。 這使得deque非常適合實現FIFO Queue
Thumbnail
2024/09/27
井字遊戲(OOXX)的遊戲描述 Tic Tac Toe(井字遊戲)是經典的雙人棋盤遊戲,在一個3x3的方格中進行。 每回合兩個玩家輪流選一個位置,先讓自己的符號(是 X 或 O)在 水平線、垂直線或對角線上連成一線的玩家宣告獲勝。
Thumbnail
2024/09/27
井字遊戲(OOXX)的遊戲描述 Tic Tac Toe(井字遊戲)是經典的雙人棋盤遊戲,在一個3x3的方格中進行。 每回合兩個玩家輪流選一個位置,先讓自己的符號(是 X 或 O)在 水平線、垂直線或對角線上連成一線的玩家宣告獲勝。
Thumbnail
2024/09/23
深入探討圖(Graph)的基本概念 及 最短路徑Shortest Path的尋找。 我們專注於廣度優先搜尋(BFS)演算法,以等權圖的最短路徑為例, 詳細說明如何利用BFS從起點擴散到終點,並且提供詳細的程式碼範例。 透過實作,讀者能夠更清楚理解圖論及BFS的應用,並體會水波紋擴散模型的重要性。
Thumbnail
2024/09/23
深入探討圖(Graph)的基本概念 及 最短路徑Shortest Path的尋找。 我們專注於廣度優先搜尋(BFS)演算法,以等權圖的最短路徑為例, 詳細說明如何利用BFS從起點擴散到終點,並且提供詳細的程式碼範例。 透過實作,讀者能夠更清楚理解圖論及BFS的應用,並體會水波紋擴散模型的重要性。
Thumbnail
看更多
你可能也想看
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給定我們一個輸入陣列nums,要求我們掃描美個陣列元素nums[i],計算除了nums[i]以外的陣列元素連乘積。 題目的原文敘述 測試範例 Example 1: Input: nums = [1,2,3,4] Output: [24,12,8,6] nums[0] 以
Thumbnail
題目敘述 題目會給定我們一個輸入陣列nums,要求我們掃描美個陣列元素nums[i],計算除了nums[i]以外的陣列元素連乘積。 題目的原文敘述 測試範例 Example 1: Input: nums = [1,2,3,4] Output: [24,12,8,6] nums[0] 以
Thumbnail
題目敘述 題目會給我們一個輸入陣列nums,和一個指定的k值。 請問,在輸入陣列nums中,有幾個子陣列的元素總合恰好為k ? 例如: nums = [1,2,3], k = 3 則有兩個子陣列的元素總合為3,分別是[1,2] 和 [3] 如果是第一次聽到或接觸前綴和prefix的同學
Thumbnail
題目敘述 題目會給我們一個輸入陣列nums,和一個指定的k值。 請問,在輸入陣列nums中,有幾個子陣列的元素總合恰好為k ? 例如: nums = [1,2,3], k = 3 則有兩個子陣列的元素總合為3,分別是[1,2] 和 [3] 如果是第一次聽到或接觸前綴和prefix的同學
Thumbnail
題目敘述 題目會給我們一個陣列,要求我們返回 兩數之和=target所在的陣列索引值。 題目還額外保證,一定剛好有一組解。 測試範例 Example 1: Input: nums = [2,7,11,15], target = 9 Output: [0,1]
Thumbnail
題目敘述 題目會給我們一個陣列,要求我們返回 兩數之和=target所在的陣列索引值。 題目還額外保證,一定剛好有一組解。 測試範例 Example 1: Input: nums = [2,7,11,15], target = 9 Output: [0,1]
Thumbnail
老是從頭重算可不是好法子,把加過的累積值存起來備用,這才符合 Prefix Sum 的精神!
Thumbnail
老是從頭重算可不是好法子,把加過的累積值存起來備用,這才符合 Prefix Sum 的精神!
Thumbnail
在學習過比較基本的DP模型 費式數列、爬樓梯、找零錢...等之後, 來看一個比較進階而且實用的DP模型,前綴和(Prefix sum), 可以再加以延伸推廣,來計算 區間和(Range Sum)。
Thumbnail
在學習過比較基本的DP模型 費式數列、爬樓梯、找零錢...等之後, 來看一個比較進階而且實用的DP模型,前綴和(Prefix sum), 可以再加以延伸推廣,來計算 區間和(Range Sum)。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News