前缀和+哈希表 连续的子数组和 leetcode53题

Posted milaiko

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前缀和+哈希表 连续的子数组和 leetcode53题相关的知识,希望对你有一定的参考价值。

连续的子数组和

题目

看到该题,一帮来讲能够想到使用前缀和来写。

前缀和

比如

nums = [23, 2, 4, 6,7] ,k =6
这时候会想到去用一数组 sums[n]

sum[0] = nums[0];
for(int i=1;i<n;i++)
	sum[i] = sum[i-1]+nums[i];

得到前缀和后,又得设置两个索引ij, 因为这里求的是子数组,比如[2,4]就需要 sum[3] - sum[0]然后求余得到0去判断。

前缀和+ 哈希表

但是因为nums.length <= 10^5, 而我们上面的做法的复杂度为o(n^2), 这很容易超时。要怎么做能减小时间复杂度呢?

s u m [ j ] − s u m [ i ] = n ∗ k ; t h e n   ( s u m [ j ] − s u m [ i ] ) / k = n sum[j] - sum[i] = n*k;\\\\then \\space (sum[j]-sum[i])/k = n sum[j]sum[i]=nk;then (sum[j]sum[i])/k=n

然后在仔细想一下, s u m [ j ] / k − s u m [ j ] / k = n sum[j]/k - sum[j]/k = n sum[j]/ksum[j]/k=n(这里的除法会留有浮点数)

那这样的话,只要在遍历sums的时候,当sums有两个数对k取到的余数相同,就可以实现上面的公式。

// 连续的子数组和

// 要求的是子数组总和为k的倍数
#include"head.h"
class Solution
public: 
    bool checkSubarraySum(vector<int>& nums, int k)
        int m = nums.size();
        if(m < 2)
            return false; // 连子数组的最小个数都凑不起
        

        unordered_map<int, int> mp;
        mp[0] = -1;
        int remainder = 0; //余数
        //通过余数累加的方式,去实现前缀和的思想

        for(int i=0;i<m;i++)
            remainder = (remainder + nums[i])%k;
            if(mp.count(remainder))
                int preIndex = mp[remainder];
                if(i - remainder >= 2)
                    return true;
                
            else 
                mp[remainder] = i;
            
        
        return false;
    
;

以上是关于前缀和+哈希表 连续的子数组和 leetcode53题的主要内容,如果未能解决你的问题,请参考以下文章

前缀和+哈希表 连续的子数组和 leetcode53题

LeetCode 523 连续的子数组和[前缀和 哈希表] HERODING的LeetCode之路

2021/5/29 刷题笔记和为K的子数组与前缀和哈希表

LeetCode 0525. 连续数组:哈希表 + 前缀和

2021/6/3 刷题笔记连续数组与前缀和哈希表

连续的子数组和--力扣