ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-05-27 10:08:07  阅读:263  来源: 互联网

标签:count map 974 temp int ++ prefix 整除 LeetCode


https://leetcode-cn.com/problems/subarray-sums-divisible-by-k/

 

第一眼,子数组问题,以为是滑动窗口,但是仔细想想做不了。

然后看了眼数据规模 30000,私以为可以暴力法过,但是死在了第69个测试用例。

class Solution {
    public int subarraysDivByK(int[] A, int K) {
        int count = 0;
        int temp = 0;
        for(int i = 0; i < A.length; i++){
            for(int j = i; j < A.length; j++){
                temp += A[j];
                if(temp % K == 0){
                    count++;
                }
            }
            temp = 0;
        }
        return count;
    }
}

然后瞄了一眼标签,发现哈希表这个tag,再加上这个题有点想前几天做过的前缀和的题,故使用前缀和思想。

我一开始是用前缀和找到i,j之间的和,然后判断这个和是否能被K取整,但是做出来分析一下时间复杂度还是O(n^2),一样会TLE

后来实在没办法了,瞄了一眼评论区才发现大佬们用的是余数来判断的。。

    public int subarraysDivByK(int[] A, int K) {
        int count = 0;
        HashMap<Integer,Integer> map = new HashMap<>();
        int temp = 0;
        map.put(0,1);
        for(int i = 0; i < A.length; i++){
            temp += A[i];
            //这个步骤是将负数转换成正数,为什么要这么操作呢?因为小于0的数字,除余之后得到的还是小于0。但是余数为-5 和余数为5其实可以归为一类。
            int curMod = ((temp % K) + K) % K;
            int preMod = map.getOrDefault(curMod,0);
            count += preMod;
            map.put(curMod,map.getOrDefault(curMod,0)+1);
        }
        return count;
    }

这个其实又是数学问题,我的数学是真的垃圾啊。。

同余定理:如果两个整数 a, b 满足 (a-b)%K == 0,那么有 a%K == b%K。
由此可知,如果 i,j 满足 (prefix(j) - prefix(i-1))%K == 0,那么有 prefix(i)%K == prefix(i-1)%K。
故,可以扫描一遍前缀和 prefix,利用 map 统计所有余数出现的次数,然后遍历 map 利用组合公式C(n,m) = n!/((n-m)!*m!) 来计算答案。
此时时间复杂度降到了 O(n)。

这里因为有K这个固定的数,我们就可以将map转换成数组来节省时间

    public int subarraysDivByK2(int[] A, int K) {
        int[] map = new int[K];
        ++map[0];
        int prefix = 0, res = 0;
        for (int a : A) {
            prefix = (a + prefix) % K;
            if (prefix < 0) prefix += K;
            res += map[prefix]++;
        }
        return res;
    }

 

标签:count,map,974,temp,int,++,prefix,整除,LeetCode
来源: https://www.cnblogs.com/ZJPaang/p/12970707.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有