leetcode 560. Subarray Sum Equals K 、523. Continuous Subarray Sum、 325.Maximum Size Subarray Sum Equ...

本文深入探讨了求解特定和子数组问题的算法策略,包括寻找和为k的连续子数组个数、检查是否存在和为k的连续子数组,以及求最大长度的子数组使其和等于k。通过三种不同题目的解析,展示了如何利用累加和与哈希表来高效解决这类问题。

整体上3个题都是求subarray,都是同一个思想,通过累加,然后判断和目标k值之间的关系,然后查看之前子数组的累加和。

map的存储:560题是存储的当前的累加和与个数

      561题是存储的当前累加和的余数与第一次出现这个余数的位置

      325题存储的是当前累加和与第一次出现这个和的位置

其实561与325都是求的最长长度,那就一定要存储的是第一次出现满足要求的位置,中间可能还出现这种满足要求的情况,但都不能进行存储

 

560. Subarray Sum Equals K

求和为k的连续子数组的个数

http://www.cnblogs.com/grandyang/p/6810361.html

 

如果当前的累加和减去k能找到值,一定是子数组。因为子数组一定是减去前面的值,累加和其实就是看到底减去几个值。

初始化的目的:如果当前位置和为k,那差值就是0,但是存储的值却是sum,不一定存储了0的值。

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        unordered_map<int,int> m;
        m[0] = 1;
        int sum = 0,res = 0;
        for(int i = 0;i < nums.size();i++){
            sum += nums[i];
            res += m[sum - k];
            m[sum]++;
        }
        return res;
    }
};

 

 

 

523. Continuous Subarray Sum

思路和560. Subarray Sum Equals K有些类似,因为都是找之前经过的数组的情况,只是560. Subarray Sum Equals K是和。一次循环,加每个数值,然后求余数,如果当前求余数在之前出现过,那当前的数减去之前的子数组的数就可以弥补。

错误解法:

如果一个数在hash_map中没有存储,比如10,使用m[10]不是不返回结果,而是返回0,这个0不代表value值,而是代表没有这个存储。这也是为什么下面这个代码在i = 2时就出错了,i=2时虽然hash_map中没有,但返回0,使得i - 0大于了1

class Solution {
public:
    bool checkSubarraySum(vector<int>& nums, int k) {
        unordered_map<int,int> m;
        m[0] = -1;
        int sum = 0;
        for(int i = 0;i < nums.size();i++){
            sum += nums[i];
            int tmp = (k == 0) ? sum : sum%k;
            if(i - m[tmp] > 1)
                return true;
            m[tmp] = i;
        }
        return false;
    }
};

 

正确解法:

class Solution {
public:
    bool checkSubarraySum(vector<int>& nums, int k) {
        unordered_map<int,int> m;
        m[0] = -1;
        int sum = 0;
        for(int i = 0;i < nums.size();i++){
            sum += nums[i];
            int tmp = (k == 0) ? sum : sum%k;
            if(m.count(tmp)){
                if(i - m[tmp] > 1)
                    return true;
            }
            else
                m[tmp] = i;
        }
        return false;
    }
};

 

325.Maximum Size Subarray Sum Equals k

注意,你查找的时候是查找sum-k,如果查不到应该分为两种情况,即当前sum在map中有没有值。因为实际上这里是从左向右遍历,只要你找到第一个等于某个sum的,这个值就能成为你需要的最长的子数组。

class Solution {
public:
    /**
     * @param nums: an array
     * @param k: a target value
     * @return: the maximum length of a subarray that sums to k
     */
    int maxSubArrayLen(vector<int> &nums, int k) {
        // Write your code here
        unordered_map<int,int> m;
        m[0] = -1;
        int res = 0;
        int sum = 0;
        for(int i = 0;i < nums.size();i++){
            sum += nums[i];
            if(m.find(sum - k) != m.end()){
                res =  max(res,i - m[sum-k]);
            }
            else{
                if(m.find(sum) != m.end())
                    continue;
                else
                    m[sum] = i;
            }
        }
        return res;
    }
};

 

转载于:https://www.cnblogs.com/ymjyqsx/p/10484507.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值