长度最小的子数组
leetcode 题号 209
代码随想录3.4
思路和想法总结:
思路与想法:这个题自己没有好的想法,就是单纯的两个循环进行暴力求解,第一层循环记录的是起始的位置,第二层循环是记录达到的位置,当然自己写的时候会感觉到这个不是一个很好的方案。时间复杂度也是
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int low = nums.length ;
int j,i,sum;
int flag = 0;
int flag2 = 0;
for(i = 0; i < nums.length ;i++){
sum = 0;
for(j = i; j < nums.length ; j++){
sum += nums [j] ;
if(sum >= target ){
flag = 1;
flag2 = 1;
break;
}
flag2 = 0;
}
if(flag2 == 1 && j - i + 1 < low)
low = j - i + 1;
}
if(flag == 0 && low == nums.length)
return 0;
return low;
}
}
这里的写法很多不够精简,比如说在sum > target 的范围内,就可以直接对要返回的结果进行操作,而且要多运用三目运算的形式,使得代码边的简洁,可读性更强。最后是否干改变的判断可以用三目运算看其是否被改变来进行判断。总之这里的代码自己写的很不好,要多学习简洁高效的代码格式,才会有提高,不然暴力解法都写不好。
正确解答:
(1)暴力版解法:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int sum;
int result = Integer.MAX_VALUE;
int subLength = 0;
for(int i = 0;i < nums.length; i++){
sum = 0;
for(int j = i;j < nums.length;j++){
sum += nums[j];
if(sum >= target){
subLength = j - i + 1;
result = result < subLength ? result : subLength;
break;
}
}
}
return result == Integer.MAX_VALUE ? 0:result;
}
}
(2)滑动窗口解法:
图片来源:代码随想录原书截取
滑动窗口
这里补充一下对滑动窗口的理解,滑动窗口这种思想会减少程序运行过程中重复运算的过程,它的总体思路可以认为是在寻找一个当前情况下的可行解,然后在可行解的条件下,对搜索空间进行剪枝,逐步的寻找一个最优解,这种方法很适用于连续的串或者数组问题,比如在…中寻找一个…连续的串或者数组。在写代码的时候我们要在心中假想出一个滑动窗口,然后窗口的前段收缩,窗口的后端延伸,最终我们可以获得一个最优解。这个想法很好,以后可以多多考虑。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int result = Integer.MAX_VALUE;
int sum = 0;
int i = 0;
int subLength = 0;
for(int j = 0; j < nums.length ; j++){
sum += nums[j];
while(sum >= target){
subLength = (j - i + 1);
result = result < subLength ? result : subLength;
sum -= nums[i++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}
语句中的sum -= nums[i++]是这个程序的精髓。