尺取法

题目:给定长度为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;
}

上图源自网络 

程序输出结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值