leetcode —— 523. 连续的子数组和

给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。

示例 1:

输入: [23,2,4,6,7], k = 6
输出: True
解释: [2,4] 是一个大小为 2 的子数组,并且和为 6。

示例 2:

输入: [23,2,6,4,7], k = 6
输出: True
解释: [23,2,6,4,7]是大小为 5 的子数组,并且和为 42。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/continuous-subarray-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
——————————
解题思路:
(1)维护一个数组copy_nums,数组中的每个值copy_nums[i]是nums[0]到nums[i]的总和。这样可以通过两次循环遍历copy_nums中两两数据之间的差值是否是k的倍数。

class Solution:
    def checkSubarraySum(self, nums: List[int], k: int) -> bool:
        length = len(nums)
        if length <=1:
            return False
        copy_nums = nums[:]  # 首先对原数组进行复制
        for i in range(1,length):  # 计算从nums[0]到nums[i]的累加和
            copy_nums[i] += copy_nums[i-1]
        
        for i in range(length-1):
            for j in range(i+1,length):
                ans = nums[i] + copy_nums[j] - copy_nums[i]  # 比较数组中两两之间的差值是否是k或者k的倍数
                if k==ans or (k!=0 and ans%k==0):
                    return True
        return False
            

(2)可以知道,当数组中存在连续子数组的和等于k或者k的倍数,假设为nums[i]到nums[j]之间的子数组,那么可以知道sum[i-1]%k==sum[j]%k,其中sum[i-1]是nums数组中前i-1个值之和,sum[j]是nums数组中前j个值之和。因为nums[i]到nums[j]的和为k的倍数。所以我们可以从数组第一个数据开始,计算前i个数据之和和k的余数,如果sum[i]%k == sum[j]%k,同时j-i>1,则数组中存在这样的连续子数组之和是k的倍数。

class Solution:
    def checkSubarraySum(self, nums: List[int], k: int) -> bool:
        
        if k==0:  # 当k的值为0,数组中元素都是非负的,要是条件成立,数组中必须存在两个连续的0值。
            for i in range(len(nums)-1):
                if nums[i] + nums[i+1] == 0:
                    return True
            return False
            
        res = 0
        dicts = {}    # 创建一个字典,字典的key是余数,value是对应的位置索引
        dicts[0] = -1  # 创建起始点,位置为-1,与k的余数为0,这里很重要
        for index,num in enumerate(nums):
            ans = (num + res) % k
            res = ans
            if ans in dicts.keys():  # 当找到两部分余数是一样的,同时两者之间的索引差大于1时,则返回True
                if index - dicts[ans] > 1:
                    return True
            dicts.setdefault(ans,index)  # 如果字典中不存在这余数,则创建一个余数
        return False
发布了320 篇原创文章 · 获赞 21 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_37388085/article/details/105253661
今日推荐