通常,涉及連續子陣列問題的時候,我們使用字首和來解決。
我們令$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 的子陣列個數之和。
**
classview codesolution:
#暴力#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
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 整除的情況。
**:
classview codesolution:
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
字首和的應用
題目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組測試資料。對於每組測試資料...