题目描述
给定一个数组 arr,该数组无序,但每个值均为正数,再给定一个正数 k。求 arr 的所有子 数组中所有元素相加==为 k 的最长子数组长度。要求:时间复杂度O(N),额外空间复杂度O(1)
例子:
输入: arr=[1,2,1,1,1]
输出:k=3
累加和为 3 的最长子数组为[1,1,1],所以结果返回 3。
题目解析
用滑动窗口
- 起始窗口内只有第一个数,判断第一个数和k的大小。
- 如果窗口内的数字的和大于k,则需要将窗口左边界向右移,继续比较
- 如果窗口内的数字的和小于k,则需要将窗口右边界向右移,继续比较
class Solution {
public:
int getMaxLength(std::vector<int> arr, int k) {
if(arr.empty() || k <= 0){
return 0;
}
int left = 0;
int right = 0;
int sum = arr[0];
int len = 0;
while (right < arr.size()){
if(sum == k){
len = std::max(len, right - left + 1);
sum -= arr[left++];
}else if(sum < k){
right++;
if(right == arr.size()){
break;
}
sum += arr[right];
}else{
sum -= arr[left++];
}
}
return len;
}
};
小结
关于各种子数组的和sum小于或者等于k这一类问题的总结
- 当数组中全是正数的时候 用双指针算法
- 当数组中包括负数的时候用 前缀和 单调队列
如果在使用前缀和求解的过程中 时间复杂度超时的情况
优化的方法主要有1、hash表 2、单调队列
类似的题目有:
-
- 长度最小的子数组
-
- Maximum Subarra
-
- Subarray Sum Equals K
-
- Shortest Subarray with Sum at Least K