【力扣】974:和可被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]

提示:

1 <= A.length <= 30000
-10000 <= A[i] <= 10000
2 <= K <= 10000

這是昨天的【每日一題】,當時沒想出來,允悲,明明是一道很簡單的題,但是窗戶紙沒捅破就死活想不出來。

算法思路

本來這種題是可以用暴力方法破解的,但是在力扣裏大部分的暴力破解都會被檢測例子制裁。

class Solution:
    def subarraysDivByK(self, A, K: int) -> int:
        n=0
        res=0
        ls=[0]
        for i in A:
            n+=i
            ls.append(n)
        for i in range(1,len(ls)):
            for j in range(i):
                if (ls[i]-ls[j])%K==0:res+=1
        return res

以上是最暴力最無腦的方法,檢查所有的子數組可能性,要說有什麼可取之處,就是使用ls保存了所有從0-i的數組和,然後通過減法得到i-j的子數組和。

class Solution:
    def subarraysDivByK(self, A, K: int) -> int:
        n=0
        res=0
        ls={0:1}
        for i in A:
            n+=i
            for j in ls.keys():
                if (n-j)%K==0:
                    res+=ls[j]
            ls[n]=ls.get(n,0)+1
        return res

以上依然是暴力循環,但是又做了一點小優化,雖然沒啥用就是了。

PERFECT

但其實這道題的技巧在於!!!(n-j)%K==0實際上等價於n%K==j%K,所以所有的數組和都可以化歸到K以內的值,然後保存出現的頻率即可。

class Solution:
    def subarraysDivByK(self, A, K: int) -> int:
        n=0
        res=0
        ls={0:1}
        for i in A:
            n+=i
            tp=n%K
            if tp in ls:
                res+=ls[tp]
            ls[tp] = ls.get(tp, 0) + 1
        return res

執行用時 :392 ms, 在所有 Python3 提交中擊敗了50.00%的用戶
內存消耗 :17.7 MB, 在所有 Python3 提交中擊敗了100.00%的用戶

語言表述不透徹,但是有認真思考過的人應該可以看懂算法。

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