Leetcode解题(第974题)

Leetcode解题(第974题)

给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。

实例:

输入:A = [4,5,0,-2,-3,1],K=5

输出:7

解释:

有7个子数组满足其元素之和可被K=5整除:

[4,5,0,-2,-3],[5],[5,0],[5,0,-2,-3],[0],[0,-2,-3],[-2,-3]

提示:

1.<=A.length<=30000

2.-10000<=A[i]<=10000

3.2<=k<=1000


解析:

看到子数组的和,联想到使用“前缀和”的思想来解决问题


“前缀和”:数组从第0项到当前项的总和

e.g.使用一个数组Sum表示:

.Sum[0]:数组第0项到第0项的总和

.Sum[1]:数组第0项到第1项的总和

.Sum[2]:数组第0项到第2项的总和


题目转换

元素和能被 K 整除的子数组数目 有几种 i、j组合,使得 A[i] 到 A[j]之和 mod K == 0 =>

A[i]到A[j]之和等价于(Sum[j]-Sum[i-1])mod k ==0 =>

进一步等价与 Sum[j]mod k = Sum[i-1]mod k


PS:当Sum[]为负数的情况

e.g. Sum[1] = -1 , k=4. -1%4 =-1

可以得到 负数%k,所得的余数必然在(-k,0)之间,所以需要将负数得到的余数加上K变成正数


代码(python3版本)

class Solution:
	def subarraysDivByk(self,A:List[int],K:int) ->int:
		record = {0:1}
		total,ans = 0,0
		for elem in A:
			total+=elem
			modulus = total %k
			if modulus <0:
			modulus = modulus+k
			if record.get(modulus,0) is not None:
				same = record.get(modulus,0)
				ans + = same
				record[modulus] = same +1
			else:
				record[modulus] = 1
		return ans
								
						

代码关键点:

same = record.get(modulus,0)
ans += same
record[modulus]=same+1
Index 0 1 2 3 4 5 6
A 4 5 0 -2 -3 1
Sum() 0 4 9 9 7 4 5
Sum()%K 0 4 4 4 3 4 0

为什么ans 要加上same(之前取余数相同出现的次数)

e.g. 当Index=3时,Sum%k =4 出现了两次,那么Sum(3)%K - Sum(1)%K = =0,Sum(3)%K - Sum(2)%K = =0,满足条件为两个数组为[5]和[5,0]

你可能感兴趣的:(Leetcode解题(第974题))