基礎型別1 leedcode560 和為k的子陣列
給定乙個整數陣列和乙個整數 k,你需要找到該陣列中和為 k 的連續的子陣列的個數。
型別 1 :
輸入:nums = [1,1,1], k = 2
輸出: 2 , [1,1] 與 [1,1] 為兩種不同的情況。
class solution:
def subarraysum(self, nums: list[int], k: int) -> int:
sum0,sum1 = 0,0
ans = 0
// map: 字首和 -> 該字首和出現的次數
presum =
for num in nums:
sum0 += num
// 這是我們想找的字首和 num1[0..j]
sum1 = sum0 - k
// 如果前⾯有這個字首和, 則直接更新答案
if sum1 in presum:
ans += presum.get(sum1)
presum[sum0] = presum.get(sum0,0)+1 // 把字首和 nums[0..i] 加⼊並記錄出現次數
return ans
備註:
1. 這裡的乙個關鍵點就是hash表的定義,這裡是字首和:該字首和出現的次數
2. 字首和與差值k的關係:sum0 - sum1 = k
拓展:同餘原理
型別1:523. 連續的子陣列和
給定乙個包含 非負數 的陣列和乙個目標 整數 k,編寫乙個函式來判斷該陣列是否含有連續的子陣列,其大小至少為 2,且總和為 k 的倍數,即總和為 n*k,其中 n 也是乙個整數。
示例 1:
輸入:[23,2,4,6,7], k = 6
輸出:true
解釋:[2,4] 是乙個大小為 2 的子陣列,並且和為 6。
示例 2:
輸入:[23,2,6,4,7], k = 6
輸出:true
解釋:[23,2,6,4,7]是大小為 5 的子陣列,並且和為 42。
def checksubarraysum(self, nums: list[int], k: int) -> bool:
len_nums = len(nums)
sum = 0
map =
for i in range(len_nums):
sum += nums[i]
if k!= 0:
sum = sum % k
if sum in map:
if i - map.get(sum) >1:
return true
else:
item =
map.update(item)
return false
這裡要注意3點:
1. map的定義是sum%k:第i個元素(hash鍵值為sum%k),之所以這麼設計,主要是問了hash的時候方便獲得索引i,方便滿足子陣列大小大於2的要求
2. 初始值map= 的初始化原理,帶入測試用例[0,0] 0 返回值為true
3. 演算法思路(同餘原理)
設位置 j < i :
0 到 j 的字首和 presum1 = 某常數1 * k + 餘數1
0 到 i 的字首和 presum2 = 某常數2 * k + 餘數2
當找到 餘數1 等於 餘數2時, 則 j + 1 到 i 的連續和 = presum2 - presum1 = (某常數2 - 某常數1) * k, 必為 k 的倍數, 返回true
型別2: leedcode974 和可被 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]
class solution:
def subarraysdivbyk(self, a: list[int], k: int) -> int:
presum =
ans, sum = 0,0
for num in a:
sum += num
sum = sum%k
presum[sum] = presum.get(sum,0)+1
for value in presum.value(): //key 對應的value的組合
ans += int(value*(value-1)/2)
return ans
我們令 p[i] = a[0] + a[1] + ... + a[i]p[i]=a[0]+a[1]+...+a[i]。那麼每個連續子陣列的和 sum(i,j) 就可以寫成 p[j] - p[i-1]p[j]−p[i−1](其中 0 < i < j0因此我們可以考慮對陣列進行遍歷,在遍歷同時統計答案。當我們遍歷到第 i 個元素時,我們統計以 i 結尾的符合條件的子陣列個數。我們可以維護乙個以字首和模 k 的值為鍵,出現次數為值的雜湊表,在遍歷的同時進行更新。這樣在計算以 i 結尾的符合條件的子陣列個數時,根據上面的分析,答案即為[0..i−1] 中字首和模 k 也為 p[i] mod k的位置個數,即presum[p[i]modk]。 資料結構與演算法 字首和的問題
例題 給你乙個鍊錶的頭節點 head,請你編寫 反覆刪去鍊錶中由 總和 值為 0 的連續節點組成的序列,直到不存在這樣的序列為止。刪除完畢後,請你返回最終結果鍊錶的頭節點。資料案例 輸入 head 1,2,3,3,1 輸出 3,1 輸入 head 1,2,3,3,4 輸出 1,2,4 輸入 head...
資料結構與演算法(1)
演算法 資料結構 一 演算法 1.演算法的幾個特徵是什麼。2.演算法複雜性的定義。大o 小o分別表示的含義。3.遞迴演算法的定義 遞迴演算法的兩要素。4.分治演算法的思想,經典的分治演算法 全排列 二分搜尋 歸併排序 快速排序 線性時間選擇 最接近點對問題 5.動態規劃演算法解題框架,動態規劃演算法...
資料結構與演算法(1)
1 線性表 2 棧 3 佇列 4 字串 補充 遞迴 1 樹與二叉樹 2 圖 1 查詢 2 排序 編寫相關演算法 資料結構 入門問題 1.為什麼學習資料結構?1 高階程式設計的理論指導 2 提公升編碼能力 3 面試中經常被問及,看發展潛力 2.有哪些資料結構?2.11線性結構 線性表 棧 佇列 陣列 ...