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?
分析:
最大和子序列,最长连续(或不连续)的递增(或递减)子序列,时间复杂度都是O(n),又来一个和为k的最长连续子序列,要求时间复杂度也是O(n)。首先想到朴素的方法,将所有sum[i][j] = s[j] - s[i]都计算出来,找个长度最长且和为k的子序列,复杂度为O(n^2);怎么将复杂度缩减到n呢,考虑到如果对于每个j不通过遍历的方式找到和为k的i,而是直接确定和为k的i,那么复杂度即为O(n);直接确定的方式也比较容易想到,就是用hash map。
代码:
int maxSub(vector<int> &nums, int k) { int sum = 0, maxLength = 0; unordered_map<int, int> hash; hash[0] = 0; for(int i = 0; i < nums.size(); i++) { sum += nums[i]; if(hash.find(sum - k) != hash.end()) maxLength = max(maxLength, i - hash[sum - k]); //保证结果是最长子序列,所以让靠前的sum留下来 else if(hash.find(sum) == hash.end()) hash[sum] = i; } return maxLength; }