[M前缀和] lc523. 连续的子数组和(前缀和+数学+取模性质)

1. 题目来源

链接:523. 连续的子数组和

2. 题目解析

区间和问题,很明显使用前缀和进行优化。

答案满足 (s[j]-s[i])%k=0,则等价于 (s[j]%k-s[i]%k)%k=0,即 s[j]%k==s[i]%k

故,针对每一个前缀和终点 s[j],仅需判断它之前有没有与它模 k 余数,即 s[j]%k 相同的起点 s[i]%k 存在即可。

枚举顺序:

  • 本题要求长度至少为 2,前缀和下标从 1 开始,终点 j 从 2 开始循环,每次将 s[j-2] 插入进哈希表,j-2 可能与 j 构成一个长度为 2 的答案,且算每一个终点 j 的时候,可能构成的答案均已经加入进哈希表了

在此之前,需要注意 k 值不可为 0,若 k 为 0,则需要判断是否至少存在一个长度为 2 的全 0 子数组。


时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( n ) O(n) O(n)


class Solution {
public:
    bool checkSubarraySum(vector<int>& nums, int k) {
        int n = nums.size();
        if (!k) {
            for (int i = 1; i < n; i ++ )
                if (!nums[i - 1] && !nums[i])
                    return true;
            return false;
        }
    
        vector<int> s(n + 1);
        for (int i = 1; i <= n; i ++ ) s[i] = s[i - 1] + nums[i - 1];

        unordered_set<int> S;
        for (int i = 2; i <= n; i ++ ) {
            S.insert(s[i - 2] % k);
            if (S.count(s[i] % k)) return true;
        }
        return false;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值