未排序正数数组中累加和为给定值的最长子数组的长度
题目描述
给定一个数组arr,该数组无序,但每个值均为正数,再给定一个正数k。求arr的所有子数组中所有元素相加和为k的最长子数组的长度
例如,arr = [1, 2, 1, 1, 1], k = 3
累加和为3的最长子数组为[1, 1, 1],所以结果返回3
[要求]
时间复杂度为O ( n ) O(n)O(n),空间复杂度为O ( 1 ) O(1)O(1)
输入描述:
第一行两个整数N, k。N表示数组长度,k的定义已在题目描述中给出
第二行N个整数表示数组内的数
输出描述:
输出一个整数表示答案
示例1
输入
5 3
1 2 1 1 1
输出
3
备注:
1 ≤ N ≤ 1 0 5 1 \leq N \leq 10^51≤N≤105
1 ≤ k ≤ 1 0 9 1 \leq k \leq 10^91≤k≤109
1 ≤ a r r i ≤ 100 1 \leq arr_i \leq 1001≤arri≤100
题解:
双指针。使用 left 和 right 两个指针表示子数组的左右位置,sum 表示子数组的和。分以下几种情况:
- sum == k,更新最大长度,sum -= arr[left],左指针右移(left++);
- sum < k,右指针右移(right++),sum += arr[right];
- sum > k,sum -= arr[left],左指针右移(left++)。
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 100000;
int n, k;
int a[N];
int main(void) {
scanf("%d%d", &n, &k);
for ( int i = 0; i < n; ++i ) scanf("%d", a + i);
int l = 0, r = 0;
int sum = a[0], len = 0;
while ( r < n ) {
if ( sum > k ) sum -= a[ l++ ];
else if ( sum < k ) {
if ( r == n - 1 ) break;
sum += a[ ++r ];
}
else {
len = max( len, r - l + 1 );
sum -= a[ l++ ];
}
}
return 0 * printf("%d\n", len);
}
版权声明:本文为MIC10086原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。