字首和及簡單應用

2022-06-05 04:12:07 字數 2446 閱讀 4146

通常,涉及連續子陣列問題的時候,我們使用字首和來解決。

我們令$p[i]=a[0]+a[1]+\ldots+a[i]$,那麼每個連續子陣列的和$\operatorname(i, j)$ 就可以寫成 $p[j]-p[i-1]$(其中 0 < i < j)的形式。

a、和為k的子陣列

給定乙個整數陣列和乙個整數 k,你需要找到該陣列中和為 k 的連續的子陣列的個數。

輸入:nums = [1,1,1], k = 2

輸出: 2 , [1,1] 與 [1,1] 為兩種不同的情況。

思考:「[j..i] 這個子陣列和為 $k$ 」這個條件我們可以轉化為$\operatorname[i]-\operatorname[j-1]==k$

所以我們考慮以 i 結尾的和為 k 的連續子陣列個數時只要統計有多少個字首和為 $\operatorname[i]-k$ 的 $\operatorname[j]$ 即可。我們建立雜湊表 $\operatorname$,以和為鍵,出現次數為對應的值,記錄 $\operatorname[i]$ 出現的次數,從左往右邊更新 $\operatorname$ 邊計算答案,那麼以 i 結尾的答案 $\operatorname[\operatorname[i]-k]$ 即可在 o(1) 時間內得到。最後的答案即為所有下標結尾的和為 k 的子陣列個數之和。

**

class

solution:

#暴力#def subarraysum(self, nums, k):

#res = 0

#if not nums:

#return res

#for i in range(0, len(nums)):

#s = 0

#path =

#for j in range(i, len(nums)):

#s += nums[j]##

if s == k:

#res += 1

#return res

defsubarraysum(self, nums, k):

res =0

if len(nums) ==0:

return

res

maps =

pre_num =0

for i in

nums:

pre_num +=i

if maps.get(pre_num-k):

res += maps[pre_num-k]

ifmaps.get(pre_num):

maps[pre_num]+=1

else

: maps[pre_num] = 1

return res

view code

b、和可被k整除的陣列

給定乙個整數陣列a,返回其中元素之和可被k整除的(連續、非空)子陣列的數目。

示例:輸入:a = [4,5,0,-2,-3,1], k = 5

輸出:7

解釋:有 7 個子陣列滿足其元素之和可被 k = 5 整除:

[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]

思考:判斷子陣列的和能否被 $k$ 點除就等價於判斷 $(p[j]-p[i-1]) \bmod k==0$, 根據同餘定理, 只要 $p[j] \bmod k==p[i-1] \bmod k$,就可以保證上面的等式成立。

因此我們可以考慮對陣列進行遍歷,在遍歷同時統計答案。當我們遍歷到第 i 個元素時,我們統計以 i 結尾的符合條件的子陣列個數。我們可以維護乙個以字首和模 k 的值為鍵,出現次數為值的雜湊表 $\operatorname$,在遍歷的同時進行更新。這樣在計算以 i 結尾的符合條件的子陣列個數時,根據上面的分析,答案即為 [0..i−1] 中字首和模 k 也為 $p[i] \bmod k$ 的位置個數,即 $\operatorname[p[i] \bmod k]$。

最後的答案即為以每乙個位置為數尾的符合條件的子陣列個數之和。需要注意的乙個邊界條件是,我們需要對雜湊表初始化,記錄 $\operatorname[0] = 1$,這樣就考慮了字首和本身被 k 整除的情況。

**:

class

solution:

def subarraysdivbyk(self, a: list[int], k: int) ->int:

record =

total, ans =0, 0

for elem in

a: total +=elem

modulus = total %k

same =record.get(modulus, 0)

ans +=same

record[modulus] = same + 1

return ans

view code

字首和的應用

題目1 k倍區間 給定乙個長度為 n 的數列,a1,a2,an,如果其中一段連續的子串行 ai,ai 1,aj 之和是 k 的倍數,我們就稱這個區間 i,j 是 k 倍區間。你能求出數列中總共有多少個 k 倍區間嗎?輸入格式 第一行包含兩個整數 n 和 k。以下 n 行每行包含乙個整數 ai。輸出格...

陣列 字首和 字首積及其應用

字首和 字首積也稱字首和陣列,字首積陣列。給一陣列a,字首和 新建一陣列b,陣列中每一項b i 儲存a中 0 i 的和 字尾和 新建一陣列b,陣列中每一項b i 儲存a中 i n 1 的和 字首積 新建一陣列b,陣列中每一項b i 儲存a中 0 i 的積 字尾積 新建一陣列b,陣列中每一項b i 儲...

二維字首和應用

題目描述 aw最近比較佛系,開始玩起了種田遊戲養生。aw在種田的時候遇到了乙個問題,在一塊 n m 個方格的地圖上,他想圍一塊邊長為 k 的正方形土地當做西瓜田,但是每個方格的土地肥沃度 w 並不一樣,aw想圍出一塊肥沃度之和最大的土地,請你幫幫他。輸入乙個整數t,表示t組測試資料。對於每組測試資料...