Leetcode. Maximum Size Subarray Sum Equals k

Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn’t one, return 0 instead.

Example 1:
Given nums = [1, -1, 5, -2, 3], k = 3,
return 4. (because the subarray [1, -1, 5, -2] sums to 3 and is the longest)

Example 2:
Given nums = [-2, -1, 2, 1], k = 1,
return 2. (because the subarray [-1, 2] sums to 1 and is the longest)

Follow Up:
Can you do it in O(n) time?

算法

先定义s的概念
s(i)代表子数组arr[0..i]中所有元素的累加和.
那么, arr[j..i] (0<=j<=i<=arr.length-1)的累加和为s(i) – s(j-1).

变量
sum = 0, 表示从arr[0]开始一直到arr[i]的子数组累加和.
len = 0, 表示累加和为k的最长子数组长度.

设置哈希表
key: 表示出现过的累加和sum
value: 表示某个累加和sum值出现时, 最早的位置 i.

  • 遍历数组 *
    以遍历到当前元素为arr[i]为例.
  1. 此时累加和为sum = sum + arr[i], 查看哈希表中是否存在key为sum – k的记录.
  2. 如果哈希表中存在sum-k, 则取出对应的value, 记为j. 那么 arr[j+1, i]的累加和为s[i] – s[j] = sum – (sum -k) = k. 因为j是累加和为sum-k最早出现的位置, 所以arr[j+1..i]是以arr[i]结尾的, 累加和为k的最长子数组. 如果 i – j 大于len, 则更新len.
  3. 如果哈希表中不存在value为sum-k的记录, 继续步骤2.
  4. 如果哈希表中不存在累加和为sum的记录, 将记录<sum, i>插入到哈希表中
  5. 继续遍历下一个元素, 直到所有元素遍历完.
  • 边界条件*
    对于 arr[0..i] 的累加和, 可以表示为 s(i) – s(-1), 即累加和为0的最早出现的位置为-1.

实现

int maxSubarraySumK(std::vector<int>& nums, int target)
{   
    if (nums.size() == 0)
    {   
        return 0;
    }   
    int maxLen = 0;
    std::map<int, int> sum2IndexMap;
    sum2IndexMap[0] = -1; 
    int sum = 0;
    for (int i = 0; i < nums.size(); ++i)
    {   
        sum = sum + nums[i];
        auto iter = sum2IndexMap.find(sum - target);
        if (iter != sum2IndexMap.end())
        {   
            maxLen = std::max(i - iter->second, maxLen);
        }
        if (sum2IndexMap.find(sum) == sum2IndexMap.end())
        {
            sum2IndexMap.insert(std::make_pair(sum, i));
        }
    }
    return maxLen;
}

};

    原文作者:周肃
    原文地址: https://www.jianshu.com/p/4e46093918f5
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞