[算法随想录]数组——leetcode209长度最小的子数组

题目链接

暴力枚举

使用两个for循环,分别表示两个边界——左边界和右边界;时间复杂度为O(n^2)

// @lc code=start
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left;
        int right;

        int ans=Integer.MAX_VALUE;
        for(left=0; left<nums.length; left++){
            int sum=0;
            for(right=left; right<nums.length; right++){
                sum+=nums[right];
                if(sum>=target){
                    ans=Math.min(ans, right-left+1);
                    break;
                }
            }
        }

        return ans==Integer.MAX_VALUE ? 0:ans;
    }
}
// @lc code=end
前缀和+二分搜索 

前缀和:新建的一个数组,sum[i]表示前i个元素的和

 要找的满足条件sum[i]-sum[j]>=target,即sum[i]>=sum[j]+target

使用两个for,对于每个sum[i]进行二分搜索其后面的j,所以复杂度为O(nlog(n))

能够使用二分搜素的原因:数组均为非负,所以前缀和为递增数列,可以使用二分搜索。

基础知识补充 

1.在给答案变量赋初值时,可以用Integer.MAX_VALUE

2.二分搜索在java里可以使用现有库函数:Arrays.binarySearch(数组名, 目标值);——见笔记

3.Math.min(a, b);  比较a,b两个元素哪个更小,多学一个函数

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int sum[]=new int[nums.length+1];
        sum[0]=0;
        int ans=Integer.MAX_VALUE;
        //为前缀和数组赋值
        for(int i=1; i<sum.length; i++){
            sum[i]=sum[i-1]+nums[i-1];
        }
        //对每个i进行二分查找
        for(int i=1; i<sum.length; i++){//个人总把sum和num长度作为边界条件时搞混
            int temp=target+sum[i-1];//确定每个i所需的bound——难点
            int bound=Arrays.binarySearch(sum, temp);

            if(bound<0)bound=-bound-1;//对Arrays.binarySearch的掌握程度
            if(bound<=nums.length)ans=Math.min(ans, bound-i+1);
        }

        return ans==Integer.MAX_VALUE ? 0:ans;
    }
}
滑动窗口 

官方题解说的很好了,直接上码:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int ans=Integer.MAX_VALUE;
        int start=0;int end=0;int sum=0;
        while(end<nums.length){
            sum+=nums[end];
            
            while(sum>=target){
                ans=Math.min(ans, end-start+1);
                sum-=nums[start++];
            }
            end++;//放哪里?????——其始终指向sum序列中的首元素和末尾元素
        }

        return ans==Integer.MAX_VALUE ? 0:ans;
    }
}

1.其实,方法二前缀和和方法三滑动窗口都有一个共同的特点:在得到一个新答案时,和旧答案相比是否比旧答案更优,更优则替换。 初始答案赋值都是将其赋值为Integer.MAX_VALUE或Integer.MIN_VALUE。借鉴

2.最终结果return都是使用?运算符,如果结果为结果变量初始赋值,那么返回0(不要遗漏)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值