题目:给定长度为n的数列整数a0,a1,a2,a3 ..... an-1以及整数S。求出综合不小于S的连续子序列的长度的最小值。如果解不存在,则输出0。
思路:尺取法,指定两个变量i,j来指定数组下标,起始位置均为0
分为三步
1.向右移动j变量,使a[i] 到 a[j] 的元素之和 大于等于S,注意 根据模板写的循环中,j的值需要-1才为该序列中最后数的下标。
如果加到最后j=n时依旧小于S,则不存在。
2.向右移动i变量,使a[i]到a[j]的元素之和小于S,加上在这之前的元素,即为以j为右端点的不小于S的连续子序列的长度的最小值
3.使用第2步算出的小于S的数,继续重复第一步右移j,直至出现第一步中不存在的情况,或j遍历完成。
#include<stdio.h>
#define min(a,b) (a>b?b:a)
// 在给的一组数据中找到不大于某一个上限的"最短连续子序列"
int findSumK(int a[],int n,int m) {
int i,j;
i=0;
j=0;
int ans = n+1;
int sum = 0;
while(j<n) {
while(sum < m && j<n) {
sum += a[j];
j++;
}
if(sum < m) { //如果加到最后都加不到sum即没有了
break;
}
while(sum >= m) {
sum -=a[i];
i++;
} // i的最后值为 左边符合条件下标值+1
printf("a[%d]~a[%d]的值为%d \n",i-1,j-1,sum+a[i-1]); // 此时ij都为下标+1,同时i也是<m的序列的首个下标
ans = min(ans,j-i+1);
}
return ans;
}
int main() {
int a[10]={5,1,3,5,10,7,4,9,2,8};
printf("最短连续子序列的长度为%d",findSumK(a,10,15));
return 0;
}
上图源自网络
程序输出结果: