LeetCode双题:滑动窗口破解最小子数组

1.长度最小的子数组

题目链接:209. 长度最小的子数组 - 力扣(LeetCode)

解法⼀:暴力求解(会超时)

算法思路:
「从前往后」枚举数组中的任意⼀个元素,把它当成起始位置。然后从这个「起始位置」开始,然后寻找⼀段最短的区间,使得这段区间的和「⼤于等于」⽬标值。
将所有元素作为起始位置所得的结果中,找到「最⼩值」即可。

算法代码:

复制代码
    // 枚举所有可能的起始位置
    for (int start = 0; start < n; ++start) {
        int sum = 0;

        // 从 start 开始扩展子数组,直到和满足条件
        for (int end = start; end < n; ++end) {
            sum += nums[end];

            if (sum >= target) {
                // 以 start 开头的最短子数组已经找到
                result = min(result, end - start + 1);
                break;
            }
        }
    }

    // 若没有符合条件的子数组,返回 0
    return result == INT_MAX ? 0 : result;
}

解法二(滑动窗口及同向双指针):

算法思路:
本题求解的对象是一段连续的区间,因此可以借助滑动窗口的思想来处理。我们让滑动窗口始终满足:从位置 i 开始,窗口内所有元素之和小于 target。这样一来,当窗口内元素之和第一次大于等于目标值时,就得到了以 i 为起点、满足条件的最短子数组长度。

具体做法:不断将右端元素划入窗口,并统计当前窗口内元素的总和:
▪ 如果窗口内元素之和大于等于 target:更新结果,同时将左端元素划出窗口,并继续判断是否仍满足条件、继续更新结果(因为左端元素可能很小,划出之后窗口内元素之和依然满足条件)。
▪ 如果窗口内元素之和仍不满足条件:执行 right++,让下一个元素进入窗口。
C++算法代码:


时间复杂度:虽然代码是两层循环,但 left 指针和 right 指针都是不回退的,两者最多都往后移动 n 次,因此时间复杂度是 O(N)。

2.将x减到0的最小操作数(medium)

题目链接:1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)

题目分析:

我们发现如果直接按要求来解题是很困难的,情况十分复杂。因此正难则反,我们可以换一种思考方式,若从两边下手难我们可以从中间下手,我们可以转化成求数组内⼀段连续的、和为 sum(nums) - x 的最⻓数组。此时,就是熟悉的「滑动窗⼝」问题了。

算法流程:

a.令 target = sum(nums) - x。若 target < 0,则问题无解;

b. 初始化左右指针 l = 0, r = 0(滑动窗口区间为 [l, r),必须明确左闭右开,确保与代码一致);用变量 sum 记录当前窗口内数组元素之和,初值为 0;用 maxLen 记录当前满足条件的数组最大区间长度,初值为 -1

c. 当 r 小于等于数组长度时,持续循环:

i. 若 sum < target,右移右指针,直到变量和大于等于 target,或右指针已到达末尾;

ii. 若 sum > target,右移左指针,直到变量和小于等于 target,或左指针已到达末尾;

iii. 如果经过上述两步调整后 sum == target,则更新满足条件的最大区间长度,并让下一个元素进入窗口;

d. 循环结束后,若 maxLen 具有有效值,则返回对应计算结果;否则返回 -1

C++算法代码:

注意left越界问题

相关推荐
一隅论数智2 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
倒头就睡的小比特2 天前
算法竞赛C++常用的STL
c++·算法
weilx12342 天前
C++笔记-文件IO-<fcntl.h>
c++
上海广测检测科技有限公司2 天前
智能平板出口巴西合规详解:Anatel射频、Inmetro电源/电池与LGPD数据合规叠加
经验分享
小羊没烦恼!2 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼2 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
FLJwu2 天前
存储与固件量产实战01:运动相机TF卡量产翻车实录!V30≠4K可用,90%OEM踩中的隐形售后坑
经验分享·数码相机·相机
Smileyqp沛沛2 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车2 天前
C/C++ 为什么需要编译器?
开发语言·c++
深圳老胡2 天前
STM32F407 控制 L6470 步进电机驱动 —— 控制过程简介
笔记·stm32·单片机·嵌入式硬件·代码规范