【LeetCode】209.长度最小的子数组

【LeetCode】209.长度最小的子数组

思路

首先我们可以简单粗暴的求解,遍历数组,从每次遍历数组时依次向后累加元素,再与target比较。

暴力求解

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {

        int j = 0;
        int size = nums.size();
        int ret = INT32_MAX;//INT32_MAX表示int类型的最大值
        //同理INT32_MIN表示int类型的最小值

        for (int i = 0; i < size; ++i)
        {
            int sum = 0;
            for (int j = i; j < size; ++j)
            {
                sum += nums[j];
                if (sum >= target)
                {
                    ret = j - i + 1 < ret ? j - i + 1 : ret;//比原ret小才替换
                }
            }
        }

        return ret == INT32_MAX ? 0 : ret;
        //判断ret是否改变,若ret没改变说符合条件的子数组,要返回0
    }
};

解析

以下图为例

i=0时,2+3+1+4=10>target,此时j=3,j-i+1=4对应该连续数组的长度,后面在依次用i遍历,找出最短的数组大于target的数组。

此代码的空间复杂度为O(n^2),空间复杂度为O(1),由于时间复杂度太高,所以leetcode上跑不过去。

滑动窗口

暴力求解中,我们使用了循环累加的方法,而滑动窗口的主要思想就是通过不断调节左右数组的边界,来找到其合适的位置,通过循环来控制窗口的右边界,再通过一个while来调整窗口的左边界。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int size = nums.size();
        int ret = INT32_MAX;
        int left = 0;
        int sum = 0;
        for (int right = 0; right < size; ++right)
        {
            sum += nums[right];
            while (sum >= target)
            {
                ret = right - left + 1 < ret ? right - left + 1 : ret;
                sum -= nums[left++];
            }
        }
        return ret == INT32_MAX ? 0 : ret;
    }
};

解析

仍然以上图为例,我们不断调整left和right的边界,就像是在移动这个红色的窗口一样。

起始位置left=0,循环过程中当right=3时,sum=8>target,记录下此时子数组的长度,这时候我们就开始要“微操”了,我们尝试让sum减去nums[0]看sum是否仍然比target大,若大于或等于target正好更新子数组的长度,若比target小则开始扩展右窗口(即继续for循环)。

此时时间复杂度为O(n),空间复杂度为O(1)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值