LeetCode刷题笔记974:和可被 K 整除的子数组(Python实现)

题目描述:

给定一个整数数组 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

这道题与LeetCode 560:和为K的子数组 非常相似,只需要将if判定条件修改一下即可

Solution1:暴力破解,时间复杂度为O(N^2),但是在提交过程中超出时间限制

class Solution:
    def subarraysDivByK(self,A,K):
        '''
        
        :type A: List[int]
        :type K: int
        :rtype: int
        '''
        count = 0
        for i in range(len(A)):
            sum = 0
            for j in range(i,len(A)):
                sum+=A[j]
                if sum % K == 0:
                    count+=1
        return count

Solution2:

既然是看有没有子数组能被能被K整除,那么我们可以设count_mod_i = (A[0] + A[1] + A[2] +·······+A[i])%K,count_mod_j = (A[0] + A[1] + A[2] +·······+A[i] + A[i+1] + ······ +A[j])%K,这里 j>i,若count_mod_j - count_mod_i=0,那么从A[i]到A[j]这子数组必然能被K整除,举个例子:

A=[4,5,0,-2,-3,1],K=5.

第一个数即A[0]=4,只算到i=0即A[0]的和,然后对K做模运算:A[0]%5=4,然后j=1,即第二个数A[1],计算A[0]到A[1]的和然后做模运算:(A[0]+A[1])%5=4,二者相等(这算一种情况),这说明A[0]到A[1]之间的子数组和即A[1]能被5整除,事实也证明:A[1]=5确实能被5整除。然后将这所有的情况(相同余数的次数)分别记录下来。假如得到余数为4的次数为1,那么单单针对这种情况的子数列的个数为1*(1-1) /2= 0,因为只出现一次这种情况(余数为4),是不符合一开始我们说的那种思想的。假如得到余数为4的次数为2,那么单单针对这种情况子数列的个数为2*(2-1)/2=1。最后将所有情况加和

代码:

import collections

class Solution:
    
    def subarraysDivByK(self,A,K):
        '''
        :param A: list[int]
        :param K: int
        :return: int
        '''
        count_mod = [0]
        for num in A:
            count_mod.append((count_mod[-1]+num) % K)
    
        count = collections.Counter(count_mod)
        return sum((v-1)*v/2 for v in count.values())
        
        
            

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值