每日LeetCode-和可被 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. 1 <= A.length <= 30000 2.
摘要由CSDN通过智能技术生成
题目: 
		给定一个整数数组 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.	1 <= A.length <= 30000
		2.	-10000 <= A[i] <= 10000
		3.	2 <= K <= 10000

这道题目用暴力破解法的结果 – 计算结果超时 … 嗯, 果然还是不能偷懒的
话不多说,直接点出这道题的核心思想- 同余原理
(恍然大悟的同学请直接跳到最后看代码)

名词解释:
两个整数a、b,若它们除以整数m所得的余数相等,则(a-b)可以整除m

(再没看明白的同学请手动算下下面的方程)

方程1: Ax – y = 0
方程2: Bx – y = 0
方程1 – 方程2 : (A-B)x = 0

到此,原理解释清楚了, 回归题目
现在有数组A, k=5
在这里插入图片描述
A[0]到A[3]的和sum1=26,除5,余1
A[0]到A[5]的和sum2=31,除5,余1
根据同余原理,(sum2-sum1)%K = 0,实际计算结果也是如此
换个角度,就是说A[4],A[5]这个子数组满足可被K整除的条件
在这里插入图片描述
这样,我们通过找到两个除以K具有相同余树的和,就可以得到一个满足条件的子数组,以此类推,有3个这样的和,就多增加了2个满足条件的子数组(c-a, c-b),有4个这样的和,就多了3个满足条件的子数组(d-c, d-b, d-c)
因为这样的和都是从A[0]累加的,所以对于数组A,只需要遍历一遍就可以了

每次累加后,算出的余数是不一样的,怎么统计呢?
这里我们使用Map来存储每个余数的个数
Key:余数
Value:sum%K得到的余数的个数
还有最后一个小步骤,我们需要对Map进行初始化,因为sum本身就可以被K整除的情况需要考虑进去
好啦,到这里,终于可以愉快地写代码啦:

public static int subarraysDivByK
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值