01求长度最小的子数组长度

34 阅读1分钟

题目

image.png

法一:暴力法

  • 用两层for循环,找出所有符合条件的结果,存进数组中。

  • 最后遍历数组,找出最小值,即长度最小。

  • 时间复杂度O(n的平方)

  • 空间复杂度O(n)

#include<stdio.h>
int main(){	
//	int len,s,nums[100],i,j,sum,c;
//	scanf("%d%d",&len,&s); 自定义输入 
//	for(i=0; i<len; i++)
//		scanf("%d",&nums[i]); 
	int s=7,nums[]={2,3,1,2,4,3},i,j,sum,c;
	int len=sizeof(nums)/sizeof(nums[0]);
	int a[100]={0},k=0;//将符合条件的长度存进数组中 
	for(i=0; i<len; i++){
		c=0;//存放元素个数 
		sum=0;//存放和 
		for(j=i; j<=len; j++){
			if(sum<s){
				sum+=nums[j];
				c++;
			}else{
				a[k++]=c;//符合条件的长度存进数组中 
				break;
			}
		}
	}
	int min=a[0];//求最小长度 
	for(i=1; i<k; i++){
		if(min>a[i]) min=a[i];
	}
	printf("%d",min);
	return 0;
} 

法二:双指针法。

  • 假设最小长度为数组长度。设头指针i、尾指针j,都指向数组中第一个元素。

  • 遍历数组,当元素和小于给定整数s时,尾指针向后移,sum加上对应元素的值;当sum符合要求(sum>=s)时,头指针向后移,sum减去对应元素的值。

  • 时间复杂度O(n)

  • 空间复杂度O(1)

#include<stdio.h>
int main(){
	int s=7,nums[]={2,3,1,2,4,3};
	int len=sizeof(nums)/sizeof(nums[0]);
	int i,j,sum=0;
	int min=len;//假设为最大长度
	i=0;//i为起始指针,j为终止指针 
	for(j=0; j<len; j++){
		sum+=nums[j];
		while(sum>=s){//满足条件,移动起始指针 
			min=min>(j-i+1) ? (j-i+1) : min;
			sum-=nums[i++];//起始指针移动了,sum也要变 
		}
	} 
	printf("%d",min); 
	return 0;
}