LeetCode209. 长度最小的子数组
题目描述#
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例#
- 输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。 - 输入:target = 4, nums = [1,4,4]
输出:1 - 输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
提交代码与结果
class Solution {
public int minSubArrayLen(int target, int[] nums) {
for(int i=0;i<target;i++){
for(int j=0;j<nums.length;j++){
//j-i==-1则当前长度i对于数组已经越界最小方向
if((j-i)>=0){
int sum=0;
for(int k=0;k<=i;k++){
sum+=nums[j-k];
}
if(sum>=target)return i+1;
}
//(j+i)==nums.length代表数组在右边已经越界
if((j+i)<=nums.length-1){
int sum=0;
for(int k=0;k<=i;k++){
sum+=nums[j+k];
}
if(sum>=target)return i+1;
}
}
}
return 0;
}
}
学习到的东西#
第一次的代码,我个人当时还以为是target^2*n的时间复杂度来着,而且是按照示例给出的数组进行构思来着,没有想到如果target足够大,甚至比nums的长度还要大的时候,算法就退化成O(n^2)了。也确实是个人考虑太简单了。
从大佬那学到的方法为滑动窗口方法,其实也是双指针法,也就是执行起来很像滑动窗口而已。
左右指针分别代表滑动窗口的左右边界,右指针就是for循环内的i,每次循环都会将左右边界内的若干数值进行相加,如果结果满足条件(sum>=target),则会将当前滑动窗口的长度和之前的长度相比较,直至结束才能确定最小的滑动窗口也就是结果数组长度的最小值。继而将窗口的左边界向右移动一位并将左指针指向的值从窗口和中剪掉,再次判断是否满足条件,以此来得到更小的结果数组的长度。
最终得到此题的个人代码#
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left=0;
int sum=0;
int resultLength=Integer.MAX_VALUE;
//滑动窗口
for(int right=0;right<nums.length;right++){
sum+=nums[right];
while(sum>=target){
//求出最小的子序列长度
//计算当前符合条件的子序列长度
resultLength=Math.min(resultLength,right-left+1);
sum-=nums[left++];
}
}
return resultLength==Integer.MAX_VALUE?0:resultLength;
}
}
作者:whitePuPigeon
出处:https://www.cnblogs.com/whitePuPigeon/p/17765685.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理