[LeetCode] (medium) 523. Continuous Subarray Sum

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,这个零不仅不会造成错误解,还是必要的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值