前綴和、哈希用法總結

思路:遇到這種連續子數組的問題,通常有的方法:

  • 滑動窗口法(先通過移動right到達包涵要求的解,然後left再優化,而這個題目不符合這種要求)
  • 動態規劃(最長連續上升子序列)
  • 前綴和

1.【leetcode560】和爲K的子數組

給定一個整數數組和一個整數 k,你需要找到該數組中和爲 k 的連續的子數組的個數。

示例 1 :

輸入:nums = [1,1,1], k = 2
輸出: 2 , [1,1] 與 [1,1] 爲兩種不同的情況。
說明 :

數組的長度爲 [1, 20,000]。
數組中元素的範圍是 [-1000, 1000] ,且整數 k 的範圍是 [-1e7, 1e7]。

思路:前綴和根本思路在於推導presum[j] - presum[i - 1] = sum(i, j),如果presum[j] - presum[i - 1]=k,那麼presum在生成的過程中,利用哈希表查找是否存在presum-k的元素存在,記錄presum-k存在的次數即爲和presum組合的子數組的個數;還要注意邊界即一個元素也需要記錄個數。

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        hashmap = {0:1}
        presum = 0
        res = 0
        for i in range(len(nums)):
            presum += nums[i]
            if presum - k in hashmap:
                res += hashmap[presum - k]
            hashmap[presum] = hashmap.get(presum, 0) + 1
        return res

2.【leetcode974 和可被 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]

思路:推導過程presum[j] - presum[i - 1] = sum(i, j),若數字a和b分別除以數字c,若得到的餘數相同,那麼(a-b)必定能夠整除c,這裏哈希表存儲的是餘數。

class Solution:
    def subarraysDivByK(self, A: List[int], K: int) -> int:
        presum = 0
        res = 0
        a = 0
        hashmap = {0:1}
        for i in range(len(A)):
            a += A[i]
            presum = a % K
            if presum in hashmap:
                res += hashmap[presum]
            hashmap[presum] = hashmap.get(presum, 0) + 1
        return res

3.【leetcode523】

思路:這個哈希的鍵值是餘數和索引值,注意初始情況,k==0的情況

class Solution:
    def checkSubarraySum(self, nums: List[int], k: int) -> bool:
        #注意:1.k == 0;2.至少包括兩個數i - hashmap[presum] > 1;3.使用if presum in hashmap:而不是hashmap.get(presum)
        res = False
        if len(nums) == 0:
            return res
        hashmap = {0:-1}
        presum = 0
        a = 0
        for i in range(len(nums)):
            a += nums[i]
            presum = a % k if k != 0 else a
            # print(hashmap.get(presum))存索引時不要這樣,因爲可能下標爲0這樣就跑到else那裏去了
            if presum in hashmap:
                # print(i, hashmap[presum])
                if i - hashmap[presum] > 1:
                    res = True
            else:
                hashmap[presum] = i
            # print(hashmap)
        return res

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章