leetcode209 长度最小的子数组(C++)

leetcode209 长度最小的子数组(C++)


本文参考卡哥的代码随想录,加上了一点自己的理解,感谢Carl的分享。
代码随想录
视频讲解

一. 题目

力扣209题
给定一个含有 n 个正整数的数组和一个正整数 target ,找出该数组中满足其和 ≥ target 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
提示:

1 <= target <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5

二. 解题思路

1.暴力解法

使用两个指针,第一个指针nums[i]用来遍历数组。nums[i]指向数组的第一个元素后,第二个指针nums[j]依次指向后面的元素,目的是将第一个元素与后面的元素依次相加,直到判断出__nums[i]与nums[j]所指区间的所有元素和__>=target时,记录元素个数result,此时的result一定为以 nums[i]指向的元素 为起点满足元素和>=target的最少个数。然后,将nums[i]后移一位,判断以第二个元素为起点满足条件的数组中元素个数,若是小于先前的result则进行替换。以此类推,直到指针nums[i]遍历完整个数组。

代码思路:
(result:目标数组长度;i:第一个数组指针下标;j:第二个数组指针下标;subLength:i,j 之间数组长度;sum:i,j 之间数组元素之和 )

  • 初始化result为最大整数(INT32_MAX),以便后期可以作比较。
  • 写第一个for循环用来遍历数组,且每次指针后移的时候,sum 清零。
  • for循环嵌套里第二个for循环(j = i,为起点),取所有和。
    • 如果达到期待值,计算数组长度,result值更新为最小长度。跳出第二个循环。
  • 最后返回result,若没有符合条件的数组,则返回0。

2.滑动窗口

同样使用两个指针,初始化两个指针nums[i], nums[j]均指向数组的首元素。不同之处在于我们用靠右的指针nums[j]来遍历数组。随着nums[j]的右移,依次相加各元素,记和为sum。当sum达到条件时进入循环,元素和sum减去nums[i]的值,数组指针nums[i]右移。继续判断sum是否满足条件,不断右移i,减掉nums[i]的值,直到sum<target,此时i,j范围内的数组为以nums[j]为尾端满足条件的最短数组。一次循环结束。将 j 右移,继续下次的循环判断。

代码思路:

  • 初始化result为最大整数(INT32_MAX),以便后期可以作比较。
  • 写第一个for循环( j )用来遍历数组。j右移的同时依次相加元素,记和为sum。
  • 当sum>=target时,进入循环。计算数组长度subLength = j - i + 1比较并更新result。sum = sum-num[i] ,右移i。直到sum不满足条件,跳出while循环,进入for循环,判断下一个以num[j]为末端的满足条件的数组。
  • 最后返回result,若没有符合条件的数组,则返回0。

三. 代码

暴力解法

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX; //将result设为最大值,以便后面比较
        int sum = 0;
        int subLength = 0;
        for ( int i = 0; i < nums.size(); i++) {
            sum = 0;
            for ( int j = i; j < nums.size(); j++) {
                sum += nums[j]; //计算数组和
                if ( sum >= target) {
                    subLength = j - i + 1; //计算数组长度
                    result = result < subLength ? result : subLength; //选择最小长度
                    break;
                }
            }
        }
        return result == INT32_MAX ? 0 : result; //没有期待数组则返回0
    }
};

滑动窗口解法

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX; //将result设为最大值,以便后面比较
        int sum = 0;
        int i = 0;
        int subLength = 0;
        for( int j = 0; j <nums.size(); j++) {
            sum += nums[j];
            while (sum >= target) {
                subLength = j - i + 1; 
                result = result < subLength ? result : subLength;
                sum -= nums[i];
                i++;
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值