LeetCode——974.和可被K整除的子数组

这几天力扣总算是放我这个菜鸡一马,来了一些中等难度题。和可被K整除的子数组,一看到反正最近脑子里都是双指针、滑动窗、前缀和、动态规划之类的东西。话不多说,赶紧看一看今天的题。

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subarray-sums-divisible-by-k
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

先贴一个暴力解

class Solution {
     
public:
    int subarraysDivByK(vector<int>& A, int K) {
     
        int res=0;
        int s=A.size();
        int i,j,sum;
        for(i=0;i<s;i++){
     
            sum=0;
            for(j=i;j<s;j++){
     
                sum+=A[j];
                if(sum%K==0){
     
                    res++;
                }
            }
        }
        return res;
    }
};

一看题目数据量,暴力解是无法满足时间要求的。OK,接下来进行优化,前缀和出场。
对于A的子数组,[i…j](下标),设数组前缀和P[j]为数组中j之前(包括j)的所有元素的和。子数组要满足和能被K整除,则P[j]-P[i-1]要能被K整除,则P[j]和P[i-1]对K求模的值相同,即同余定理,简单证明非常容易,此处不在详述。因此利用哈希表记录前缀和对K求余的键值,遍历时,检查对应求余的键值是否为0,若否,则存在满足条件的子数组。

class Solution {
     
public:
    /*哈希表,前缀和*/
    unordered_map<int,int> book;
    int subarraysDivByK(vector<int>& A, int K){
     
        int res=0,sum=0;
        int mod;
        book[0]=1;
        for(auto& x:A){
     
            sum+=x;
            mod=(sum%K+K)%K;
            if(book.count(mod)!=0){
     
                res+=book[mod];
            }
            book[mod]++;
        }
        return res;
    }
};

你可能感兴趣的:(算法学习,哈希表,leetcode)