标准做法
这道题的标准做法是使用滑动窗口:
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int i=0,j=0,sum=0,len=Integer.MAX_VALUE;
while(i<nums.length) {
sum+=nums[i++];
while(sum>=s) {
len=Math.min(len, i-j);
sum-=nums[j++];
}
}
return len==Integer.MAX_VALUE?0:len;
}
}
运行结果为:

解题思路
这道题的意思是给定一个数组和一个数,求这个数组中的最短连续数使得这些数字之和大于等于给定的数。
一般的做法是蛮力法:
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int minLen=Integer.MAX_VALUE;
int len=nums.length;
int[] curNums=new int[len];
for(int i=0;i<len;i++) {
for(int j=i;j<len;j++) {
if(j==i) curNums[j]=nums[j];
else curNums[j]=curNums[j-1]+nums[j];
if(curNums[j]>=s) {
if(j-i+1<minLen)
minLen=j-i+1;
if(minLen==1) return 1;
break;
}
}
}
if(minLen==Integer.MAX_VALUE) return 0;
else return minLen;
}
}
蛮力法做了一些优化,但是时间和空间消耗还是较大:

另外一种做法是从长度为1的子串开始,尝试不同的长度下子串之和是否可以大于给定的数:
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int len=nums.length;
int sum=0;
for(int k=0;k<len;k++) {
for(int i=0;i<=k;i++)
sum+=nums[i];
if(sum>=s) return k+1;
for(int i=0;i+k+1<len;i++) {
sum-=nums[i];
sum+=nums[i+k+1];
if(sum>=s) return k+1;
}
sum=0;
}
return 0;
}
}
性能稍微有一点提升,但是还是没有滑动窗口表现好:

本文介绍了使用滑动窗口解决数组中最短连续数和问题的标准做法,并对比了蛮力法和从长度为1子串开始的其他解法,强调了滑动窗口在性能上的优势。
869

被折叠的 条评论
为什么被折叠?



