zoukankan      html  css  js  c++  java
  • [leetCode]974. 和可被 K 整除的子数组

    暴力法

    计算数组前缀和,使用前缀和遍历数组连续区间。

    class Solution {
        public int subarraysDivByK(int[] A, int K) {
            int count = 0;
            int[] sum = new int[A.length + 1];
            //计算前缀之和 
            for(int i = 1; i < sum.length; i++){
                sum[i] = sum[i-1] + A[i-1];
            }
            //遍历所有区间,计算i-j之间的元素之和
            for(int i = 0; i < sum.length; i++){
                for(int j = i+1; j < sum.length; j++){
                    if((sum[j] - sum[i])%K == 0) ++count;
                }
            }
            return count;
        }
    }
    

    哈希表逐一统计

    这题利用了同余定理,如果前缀和与%K余数相同则它们之间的组和一定能构成连续子数组,其和能整除K

    class Solution {
        public int subarraysDivByK(int[] A, int K) {
            //键为前缀和%k,值为该余数出现的次数
            HashMap<Integer,Integer> record = new HashMap<>();
            record.put(0,1);//考虑整个数组本身的和整除k的情况
            int sum = 0;//前缀和
            int ans = 0;//答案
            for(int num : A){
                sum += num;
                //java中负数模运算还是负数,因此需要修正
                int mod = (sum % K + K) % K;
                int same = record.getOrDefault(mod,0);
                ans += same;//0 + 1 + 2 + 3 + 1,[4,5,-2,-3,1]
                record.put(mod,same+1);
            }
            return ans;
        }
    }
    

    哈希表 单次统计

    上面的代码对结果进行了逐一统计计算,下面代码在维护完record表后使用排列组合对结果进行计算。

    class Solution {
        public int subarraysDivByK(int[] A, int K) {
            //键为前缀和%k,值为该余数出现的次数
            HashMap<Integer,Integer> record = new HashMap<>();
            record.put(0,1);//考虑整个数组本身的和整除k的情况
            int sum = 0;//前缀和
            int ans = 0;
            //维护record
            for(int num : A){
                sum += num;
                //java中负数模运算还是负数,因此需要修正
                int mod = (sum % K + K) % K;
                record.put(mod,record.getOrDefault(mod,0)+1);
            }
            //使用排列组合,相同余数出现的总次数为entry.getValue,从中取两个进行组合
            for(Map.Entry<Integer,Integer> entry : record.entrySet()){
                ans += (entry.getValue() * (entry.getValue() - 1))/2;
            }
            return ans;
        }
    }
    
  • 相关阅读:
    开始接触开源FTP工具 FileZilla
    借船过河:一个据说能看穿你的人性和欲望的心理测试
    Git的使用方法级相关资料
    写给自己的一封信:亲爱的自己
    试用豆瓣电台2天
    HTML5 入门:一个最简单的HTML页面(doctype、meta、Head、标签的使用)
    读《乌合之众》附电子书下载
    快速了解Flash CS5六大特点
    读《每天懂一点成功概率学》
    PhotoshopCS6快捷键
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13859992.html
Copyright © 2011-2022 走看看