前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >脸书面试题 leetcode 209. 长度最小的子数组(滑动窗口)

脸书面试题 leetcode 209. 长度最小的子数组(滑动窗口)

作者头像
程序员小熊
发布2021-05-28 13:58:23
3580
发布2021-05-28 13:58:23
举报

今天给大家分享一道 facebook 的面试题,也就是 Leetcode 209. 长度最小的子数组,提供滑动窗口解题思路,供大家参考

题目:

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

示例:

输入:s = 7, nums = [2,3,1,2,4,3]

输出:2

解释:子数组 [4,3] 是该条件下的长度最小的子数组。

滑动窗口解法:

假设下标从 i 到 j 连续子数组元素和为 sum,如下图示:

如果当前的 sum 小于 s,则将下标 j 右移,将其后面一个数组元素也加入到 sum 中,如下如示:

依次类推,如果 sum 仍然小于 s,继续往下标 j 后面多加一个数组元素,直到最后 sum > s,就找到了一个满足题意的连续子数组记录长度,如下图示:

然后再从下标 i 不断右移,缩小该连续子数组的和 sum,在将 i 不断右移过程中,某一时刻 sum < s,如下图示:

此时下标 j 又开始不断右移,找到一个连续子数组的和 sum > s,依次类推。

整个过程一直保持着一个窗口,其长度不是固定的,但是是被 i 和 j 这两个索引所定义的,窗口不停向前滑动去寻找满足题意的连续子数组。

Show me the Code

代码语言:javascript
复制
// c 语言版本
int minSubArrayLen(int s, int* nums, int numsSize){
    int sum = 0;               //  窗口中数组元素的和
    int res = numsSize + 1;    //  最小的连续子数组的长度
    int left = 0, right = -1;  //  nums[left...right] 为滑动窗口
    while (left < numsSize) {
        // sum 小于 s,窗口的右边界向前拓展,但要保证右边界 right 不越界
        if ((right < numsSize - 1) && (sum < s)) {
            sum += nums[++right];
        //  sum 大于等于 s,窗口的左边界向前行进
        } else {
            sum -= nums[left++];
        }
        //  找到可行的连续子数组,取 res 和目前连续子数组的长度(前闭右闭,长度 +1)的最小值
        if (sum >= s) {
            res = res < right - left + 1 ? res : right - left + 1;
        }
    }
    // 不存在符合条件的子数组,则返回 0,否则返回最小的连续子数组的长度
    return res == numsSize + 1 ? 0 : res;
}

运行结果:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员小熊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档