• 【面试经典150 | 滑动窗口】长度最小的子数组


    写在前面

    本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……

    专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:

    • Tag:介绍本题牵涉到的知识点、数据结构;
    • 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
    • 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
    • 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
    • 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。

    Tag

    【滑动窗口】【双指针】【暴力枚举】【数组】


    题目来源

    面试经典150 | 209. 长度最小的子数组


    题目解读

    给定一个长度为 n 的数组以及一个正整数 target。找出数组中连续子数组和大于等于 target 的最小长度。


    解题思路

    方法一:暴力枚举

    最容易想到的方法是枚举所有连续子数组的,如果某个连续子数组的元素和大于等于 target,则更新最小的子数组长度。

    实现代码

    class Solution {
    public:
        int minSubArrayLen(int s, vector<int>& nums) {
            int n = nums.size();
            if (n == 0) {
                return 0;
            }
            int ans = INT_MAX;
            for (int i = 0; i < n; i++) {
                int sum = 0;
                for (int j = i; j < n; j++) {
                    sum += nums[j];
                    if (sum >= s) {
                        ans = min(ans, j - i + 1);
                        break;
                    }
                }
            }
            return ans == INT_MAX ? 0 : ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    复杂度分析

    时间复杂度: O ( n 2 ) O(n^2) O(n2)

    空间复杂度: O ( 1 ) O(1) O(1)

    方法二:滑动窗口

    我们使用一个滑动窗口在数组上进行滑动,初始滑动窗口的始末位置指针 lr 都为 0,暂时固定开始的位置不动,一直向右滑动滑动窗口的末位置 l,并及时更新滑动窗口内的数组元素和 sum

    • 如果 sum >= target,说明当前的滑动窗口范围内的数组是一个合适的连续子数组,更新 res = min(res, r - l + 1)res 初始为 INT_MAX
    • 这个时候,我们试着右移开始位置 i,判断当前的和 sum 是否还大于等于 target,如果是的,就继续右移 i 并更新 res;此时的 sum 更新只需要减去刚刚移出滑动窗口的数值即可。

    最后,如果 res = INT_MAX,说明没有合适的连续子数组,返回 0;否则返回 res

    实现代码

    class Solution {
    public:
        int minSubArrayLen(int target, vector<int>& nums) {
            int n = nums.size();
            int l = 0;
            int res = INT_MAX;
            int sum = 0;
            for (int r = 0; r < n; ++r) {
                sum += nums[r];
                while (sum >= target) {
                    sum -= nums[l];
                    res = min(res, r - l + 1);
                    ++l;
                }
            }
            return res == INT_MAX ? 0 : res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    复杂度分析

    时间复杂度: O ( n ) O(n) O(n) n n n 为数组的长度。指针 lr 最多各移动 n 次。

    空间复杂度: O ( 1 ) O(1) O(1)

    写在最后

    如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

    如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

    最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

  • 相关阅读:
    软考知识点——常见算法策略、设计模式
    从Purge机制说起,详解GaussDB(for MySQL)的优化策略
    接口防止重复提交,订单避免重复下单
    路径规划算法之刚体变换
    导出本地服务到Public Network,需有密码才能访问,7天有效时间
    【.NET深呼吸】将XAML放到WPF程序之外
    分布式电源接入对配电网影响分析(Matlab代码实现)
    ETL可视化工具 DataX -- 安装部署 ( 二)
    Sentinel 概述
    专精特新中小企业申报条件
  • 原文地址:https://blog.csdn.net/weixin_54383080/article/details/133129181