[LeetCode] (medium) 523. Continuous Subarray Sum

博客围绕LeetCode上连续子数组和问题展开,给定非负数组和目标整数k,需判断是否存在长度至少为2的连续子数组和为k的倍数。介绍了直观法和数学方法,数学方法通过取模运算,若模重复则两重复点间和为k的倍数,并给出数学推导和示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://leetcode.com/problems/continuous-subarray-sum/

Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer.

Example 1:

Input: [23, 2, 4, 6, 7],  k=6
Output: True
Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6.

Example 2:

Input: [23, 2, 6, 4, 7],  k=6
Output: True
Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42.

Note:

  1. The length of the array won't exceed 10,000.
  2. You may assume the sum of all the numbers is in the range of a signed 32-bit integer.

直观法:

class Solution {
public:
    bool checkSubarraySum(vector<int>& nums, int k) {
        if(k == 0){
            for(int i = 1; i < nums.size(); ++i){
                if(nums[i] == nums[i-1]) return true;
            }
            return false;
        }
        k = abs(k);
        unordered_set<int> S;
        for(int cur : nums){
            unordered_set<int> tem;
            for(int pre : S){
                if((pre+cur)%k == 0) return true;
                tem.insert((pre+cur)%k);
            }
            S.swap(tem);
            S.insert(cur%k);
        }
        return false;
    }
};

数学方法:

https://leetcode.com/problems/continuous-subarray-sum/discuss/150330/Math-behind-the-solutions

Haven't seen anyone post the math or theory behind the solutions yet, so I'm sharing mine. Let me know if there is any better one.
In short, start with mod =0, then we always do mod = (mod+nums[i])%k, if mod repeats, that means between these two mod = x occurences the sum is multiple of k.
Math: c = a % k, c = b % k, so we have a % k = b % k.
Where a is the mod at i and b is the mod at j and a <= b, i < j, because all nums are non-negative. And c is the mod that repeats.
Suppose b-a=d, then we have b % k = ((a+d) % k)%k = (a%k + d%k)%k
In order to make the equation valid: a % k = (a%k + d%k)%k
d%k has to be 0, so d, the different between b and a, is a multiple of k
Example:
[23, 2, 1, 6, 7] k=9
mod = 5, 7, 8, 5 <-- at here we found it

class Solution {
public:
    bool checkSubarraySum(vector<int>& nums, int k) {
        int sum=0, lastsum=0;
        unordered_set<int> S;
        
        for(int cur : nums){
            lastsum = sum;
            sum += cur;
            
            if(k) sum %= k;
            
            if(S.find(sum) != S.end()) return true;
            
            S.insert(lastsum);
        }
        
        return false;
        
    }
};

 注意最一开始会加入一个0,这个零不仅不会造成错误解,还是必要的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值