zoukankan      html  css  js  c++  java
  • leetcode 560. Subarray Sum Equals K 、523. Continuous Subarray Sum、 325.Maximum Size Subarray Sum Equals k(lintcode 911)

    整体上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;
        }
    };

    注意1.这个地方m.count(tmp) == 1的时候不要去更新m[tmp] = i,因为这样不能得到最长的长度,去判断有没有至少2个的时候,应该用最远位置去判断。

      2. i - (i - 1) >= 1其实就能表示有两个数字,但是这里是需要减去之前的所有,所以必须是i - 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(m.count(tmp)){
                    if(i - m[tmp] > 1)
                        return true;
                }
                else
                    m[tmp] = i;
            }
            return false;
        }
    };

    325.Maximum Size Subarray Sum Equals k

    这个题与523一样unordered_map中只需要保存第一个出现的位置,但保存的是sum,不是target,注意!

    注意,你查找的时候是查找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;
        }
    };
  • 相关阅读:
    远程连接桌面报:这可能是由于credssp加密oracle修正
    MVC断点续传
    [COCI2011-2012#5] POPLOCAVANJE 后缀自动机
    [SDOI2016]生成魔咒 后缀自动机
    [JSOI2009]密码 AC自动机
    CF17E Palisection manacher
    [JSOI2007]字符加密 后缀数组
    [POI2012]OKR-A Horrible Poem hash
    [APIO2014]回文串 manacher 后缀数组
    [SHOI2011]双倍回文 manacher
  • 原文地址:https://www.cnblogs.com/ymjyqsx/p/10484507.html
Copyright © 2011-2022 走看看