题目描述:
思路:先不看下面的要求,先解出结果再进行优化。先直接暴力枚举
class Solution {
public static void main(String[] args) {
int[] a={2,3,1,2,4,3};
new Solution().minSubArrayLen(7,a);
}
public int minSubArrayLen(int s, int[] nums) {
int n=nums.length;
if(n==0) return 0;
int len=n+1;
int sum=0;
for(int left=0;left<n;left++){
sum=nums[left];
if(sum>=s) {
len=1;
break;
}
for(int right=left+1;right<n;right++){
sum+=nums[right];
if(sum>=s){
len=(right-left+1)<len?(right-left+1):len;
break;
}
}
}
if(len>n)len=0;
return len;
}
}
暴力法的时间复杂度为O(n^2)那么怎样能减少呢。想到的想法是先遍历一遍数组得到数组和,之后从和中依次减去头和尾中较小的数,直到和小于s。但是动手编程时候发现这种解法有问题,当nums[left]==nums[right]时候,无法进一步判定先移动哪个指针。因此这种方法行不通。
如何继续解决能,第一次遍历数组当向和超过s时候可以停止向右,而左指针向右移,当和重新小于s时候,右指针继续前移。
class Solution {
public static void main(String[] args) {
int[] a={2,3,1,2,4,3};
new Solution().minSubArrayLen(7,a);
}
public int minSubArrayLen(int s, int[] nums) {
int n=nums.length;
if(n==0) return 0;
int sum=0;
int left=0;
int right=0;
int len=n+1;
while (right<n){
sum+=nums[right];
while (sum>=s){
len=len<(right-left+1)?len:(right-left+1);
sum-=nums[left];
left++;
}
right++;
}
if (len>n)return 0;
return len;
}
}
时间复杂度减少了很多毕竟从O(n^2)降到了O(n)
关于进阶里的用O(nlogn)则没有想法,给出官方的解答