算法31.0
974. 和可被 K 整除的子数组 - 力扣(LeetCode)
自己的理解:
暴力解法:枚举所有+判断
不能用滑动窗口是因为 这里的数字存在负数和零
细节:
算法30.0的细节问题
getOrDefault(r,0) 用于从map中获取指定键对应的值 如果键不存在则返回默认值
别人的讲解:
两个前置知识:
同余定理 (如果两个数的差值)取余一个整数是0 那么这两个数各自取余这个整数是相等的
公式是(a-b)% c = 0 可以推断 a%c = b % c
Java和c++中负数%正数的结果以及修正
负数 % 正数 = 负数
如果要修正负数为正数 修正方案是( a % p + p )% p
优化暴力解法:

问题转化为了在0 到 i-1区间内 找到有多少个前缀和的余数等于sum%k(可能是负数 需要修正)
所以问题转化为了在0到i-1区间内 找到有多少个前缀和的余数等于(sum % k + k)% k
算法30.0的启示
哈希表<int , int> 第一个int为前缀和的余数 第二个为次数
下面是题目、效果图和代码:


class Solution
{public int subarraysDivByK(int[] nums, int k) {Map<Integer,Integer> hash = new HashMap<Integer,Integer>();hash.put(0%k,1) ; //哈希表里面其实存的是前缀和的余数 int sum = 0,ret = 0;for(int x:nums) {sum += x;//计算当前位置的前缀和int r = (sum % k + k) % k;//注意修正ret += hash.getOrDefault(r,0);//统计结果hash.put(r,hash.getOrDefault(r,0)+1);}return ret;}
}
//xiyu251110&1#4*6