209. 长度最小的子数组


    /**
     * 暴力解法
     * @param target
     * @param nums
     *
     * target = 7, nums = [2,3,1,2,4,3]
     * 
     * left = 0 , 记录连续数组的起始位置
     * sum = 0 , 记录连续数组元素和
     * length = Integer.MAX_VALUE 与后续的length取小值
     * 
     * num.length = 6
     * right = 0 ,连续数组的结束位置,right < 6;
     *      sum += nums[0] = 2 < target
     * right = 1
     *      sum += nums[1] = 2 + 3 = 5 < target;
     * right = 2
     *      sum += nums[2] = 2 + 3 + 1 = 6 < target;    
     * right = 3
     *      sum += nums[3] = 2 + 3 + 1 + 2 = 8 > target;
     *      length = min(length , right - left + 1)   //right - left + 1 就是连续数组的长度
     *      将sum 置为 0 ,重新开始计算
     *      连续数组的起始位置 + 1, 此时从nums[1]开始累加
     *      连续数组的结束位置也要重置从1开始计算, 因此此时要把right = left - 1 = 0, 由于在循环条件中,下一轮right 会+1;
     *      因此此时right = 0, 下一次循环right就是从1开始计数
     *如此重复遍历即可      
     * @return
     */
    public static int minSubArrayLen(int target, int[] nums) {
        int left = 0 ;
        int sum = 0;
        int length = Integer.MAX_VALUE;
        for (int right = 0; right <  nums.length; right++) {
            sum += nums[right];
            if (sum >=target){
                length = Math.min(length , right - left +1);
                sum = 0 ;
                left ++ ;
                right = left - 1;
            }
        }
        return length == Integer.MAX_VALUE ? 0 : length;
    }


 /**
     * 优化方法 
     * @param target
     * @param nums
     * @return
     * 
     * target = 7, nums = [2,3,1,2,4,3]
     * left = 0 ,连续数组起始位置,
     * sum = 0 ,连续数组和
     * length = Integer.MAX_VALUE, 设置为最大值, 与length相比, 取小值
     * 
     * right = 0 ; right < 6 ; right ++
     * right = 0 ; sum += nums[0] = 2;
     * right = 1 ; sum += nums[1] = 5;
     * right = 2 ; sum += nums[2] = 6;
     * right = 3 ; 
     *      sum += nums[3] = 8 > target; 注意此时sum > target , 并没有将right 重置, 而是将left + 1;
     *      length = 4;   
     *      sum -= nums[0] = 6
     *      left += 1;
     * 如此循环
     */
    public static int minSubArrayLen(int target, int[] nums) {
        int left = 0;
        int sum = 0 ;
        int length = Integer.MAX_VALUE;

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值