• 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]

    前缀和+HashMap

    常规思路是:首先求得前缀和数组,然后检查每一个子数组的和是否能被K整除。这样做的时间复杂度是O(n^2),会超时,需要继续优化。优化的思路是不用检查每个子数组,而是能快速找到和能被K整除的数组。可以使用HashMap,前缀和sum[i]除以K的余数为key,该余数出现的次数为value,如果有两个余数相同的前缀和,那么它们对应的区间和就能被K整除。遍历数组,依次将对应的entry加入HashMap,记当前位置的前缀和除以K的余数为r,则前面有多少个对应前缀和余数同为r的位置,则符合条件的子数组就新增几个。
    需要注意的是两个前缀和相减对应的区间不能从下标0开始,如果当前位置的sum[i]刚好就能被K整除,则符合条件的子数组个数加1。

    class Solution {
        public int subarraysDivByK(int[] A, int K) {
            int count=0,n=A.length,s=0;
            int[] sum=new int[n];
            for(int i=0;i<n;++i){
                s+=A[i];
                sum[i]=s;
            } 
            int r=0;//r为余数
            //key为sum[i]除以K的余数,value为该余数出现的次数
            HashMap<Integer,Integer> map=new HashMap<>();
            for(int i=0;i<n;++i){
                r=(sum[i]%K+K)%K;//防止余数为负数
                if(r==0) count+=1;//如果sum[i]可以被K整除,count加1
    
                if(map.containsKey(r)){
                    count+=map.get(r);
                    map.put(r,map.get(r)+1);
                }
                else map.put(r,1);
            }
            return count;
        }
    }
    

    原题链接:https://leetcode-cn.com/problems/subarray-sums-divisible-by-k

  • 相关阅读:
    STP生成树协议
    Fiddler快速入门(还有一个功能就是不经过网络,直接模拟一个响应返回给客户端)
    Qt宏Q_OBJECT展开记录
    rem_taobaofix.js
    yield return
    NET full stack framework
    API 网关
    Redis主从高可用缓存
    数据异构解决方案缓存一致性和跨服务器查询
    NET Core 防止跨站请求
  • 原文地址:https://www.cnblogs.com/Frank-Hong/p/14175979.html
Copyright © 2020-2023  润新知