leetcode 面试经典 150 题:长度最小的子数组

news2024/12/19 15:21:27
链接长度最小的子数组
题序号209
题型数组
解题方法滑动窗口
难度中等

题目

给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

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

  • 示例 2:
    输入:target = 4, nums = [1,4,4]
    输出:1

  • 示例 3:
    输入:target = 11, nums = [1,1,1,1,1,1,1,1]
    输出:0

  • 提示:
    1 <= target <= 109
    1 <= nums.length <= 105
    1 <= nums[i] <= 104

  • 进阶:
    如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。

题解

滑动窗口法

  1. 子数组:是数组中连续的、非空元素序列。

  2. 核心要点

    • 滑动窗口:使用滑动窗口(双指针)的方法来解决这个问题。定义两个指针 left 和 right,分别表示子数组的开始和结束位置。
    • 窗口和:维护一个变量 sum,表示当前窗口内元素的和。
    • 窗口移动:当 sum < s 时,移动 right 指针向右扩展窗口,并将 nums[right] 加入 sum。当 sum ≥ s 时,记录当前窗口的长度,并尝试移动 left 指针向右缩小窗口,同时从 sum 中减去 nums[left]。
    • 最小长度:在每次满足 sum ≥ s 时,更新最小长度的记录。
  3. 时间复杂度:O(n),因为每个元素最多被访问两次(一次被 right 指针访问,一次被 left 指针访问)。

  4. 空间复杂度:O(1),因为只使用了常数级别的额外空间

  5. c++ 实现算法

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n = nums.size();
        int left = 0; // 滑动窗口左边界
        int sum = 0;  // 当前窗口的总和
        int minLength = INT_MAX; // 最小子数组长度,初始化为无穷大

        for (int right = 0; right < n; ++right) {
            sum += nums[right]; // 将当前元素加入窗口

            // 当窗口内的和满足 >= target 时,尝试缩小窗口
            while (sum >= target) {
                minLength = min(minLength, right - left + 1); // 更新最小长度
                sum -= nums[left]; // 从窗口中移除左边界的值
                ++left; // 左边界右移
            }
        }

        // 如果没有找到符合条件的子数组,返回 0
        return minLength == INT_MAX ? 0 : minLength;
    }
};
  1. 演示:以示例1为例
    在这里插入图片描述

  2. c++完整demo

#include <iostream>
#include <vector>
#include <climits> // for INT_MAX
using namespace std;

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n = nums.size();
        int left = 0; // 滑动窗口左边界
        int sum = 0;  // 当前窗口的总和
        int minLength = INT_MAX; // 最小子数组长度,初始化为无穷大

        for (int right = 0; right < n; ++right) {
            sum += nums[right]; // 将当前元素加入窗口

            // 当窗口内的和满足 >= target 时,尝试缩小窗口
            while (sum >= target) {
                minLength = min(minLength, right - left + 1); // 更新最小长度
                sum -= nums[left]; // 从窗口中移除左边界的值
                ++left; // 左边界右移
            }
        }

        // 如果没有找到符合条件的子数组,返回 0
        return minLength == INT_MAX ? 0 : minLength;
    }
};

int main() {
    Solution solution;
    vector<int> nums = {2, 3, 1, 2, 4, 3};
    int target = 7;

    int result = solution.minSubArrayLen(target, nums);
    cout << "result: " << result << endl; // 输出 2
    return 0;
}

滑动窗口法和双指针法

滑动窗口和双指针是解决数组和字符串问题中常用的两种技术,它们在某些情况下可以相互转换,但它们的概念和应用场景有所不同。下面我将分别解释这两种技术,并说明它们的主要区别。

滑动窗口

滑动窗口是一种处理 固定长度或动态长度窗口内元素的技术,常用于解决需要在连续子数组或子字符串中寻找特定属性的问题。 滑动窗口的核心思想是维护一个窗口,随着遍历的进行,窗口内包含的元素会不断变化。

特点:

  • 窗口可以是固定长度,也可以是动态变化的。
  • 窗口内的操作通常是累加、累乘或者比较。
  • 滑动窗口可以用于寻找子数组或子字符串的最大/最小值、和、乘积等。

应用场景:

  • 寻找子数组的和或乘积满足特定条件的最小/最大长度。
  • 判断子数组是否包含特定数量的不同元素。
  • 实现一些需要连续性条件的数据流统计。

双指针

双指针技术通常涉及两个指针(或索引),它们在数组或字符串中以不同的速度移动,用于解决需要比较元素之间相对位置的问题。

特点:

  • 两个指针可以同时移动,也可以一个快一个慢。
  • 双指针常用于比较、排序、去重、寻找特定模式等问题。
  • 双指针可以用于解决有序数组中的特定问题,如寻找两个数的和、差等。

应用场景:

  • 寻找两个指针之间的特定关系,如两数之和为特定值。
  • 判断一个数组是否为回文(快慢指针相向而行)。
  • 实现归并排序、快速排序中的合并和分区步骤。

区别

  • 窗口大小:滑动窗口通常有一个明确的窗口大小,而双指针不一定有固定的大小概念。
  • 移动方式:滑动窗口通常是单向移动(如向右扩展),而双指针可以相向而行或同向而行。
  • 问题类型:滑动窗口更适合解决需要连续性的问题,而双指针更适合解决需要比较元素相对位置的问题。
  • 灵活性:双指针在某些情况下比滑动窗口更灵活,因为它们可以独立控制每个指针的移动。

在实际应用中,滑动窗口和双指针可以根据问题的具体需求相互转换。例如,滑动窗口问题可以通过设置两个指针来模拟,而某些双指针问题也可以通过扩展窗口来解决。理解这两种技术的核心思想和适用场景,可以帮助你更有效地解决算法问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2262236.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录day22 | 回溯算法理论基础 leetcode 77.组合 77.组合 加剪枝操作 216.组合总和III 17.电话号码的字母组合

DAY22 回溯算法开始 学到目前最烧脑的一天 回溯算法理论基础 任何回溯算法都可以抽象成一个树结构 理论基础 什么是回溯法 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。 在二叉树系列中&#xff0c;我们已经不止一次&#xff0c;提到了回溯 回溯是递归的副…

画一颗随机数

代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>codePen - Random Tree</title> </head> <body><canvas></canvas><script>const canvas doc…

牛客周赛 Round 72 题解

本次牛客最后一个线段树之前我也没碰到过&#xff0c;等后续复习到线段树再把那个题当例题发出来 小红的01串&#xff08;一&#xff09; 思路&#xff1a;正常模拟&#xff0c;从前往后遍历一遍去统计即可 #include<bits/stdc.h> using namespace std; #define int lo…

[x86 ubuntu22.04]投影模式选择“只使用外部”,外部edp屏幕无背光

1 问题描述 CPU&#xff1a;G6900E OS&#xff1a;ubuntu22.04 Kernel&#xff1a;6.8.0-49-generic 系统下有两个一样的 edp 屏幕&#xff0c;投影模式选择“只使用外部”&#xff0c;内部 edp 屏幕灭&#xff0c;外部 edp 屏幕无背光。DP-1 是外部 edp 屏幕&#xff0c;eDP-1…

清理C盘小记

突然C盘就爆满了&#xff0c;想当初还是给他预留了120G的空间&#xff0c;感觉到现在也不够用了&#xff0c;担心出现死机的情况就赶紧进行了清理。有一说一&#xff0c;清理回收站是真的有用。 参考&#xff1a;C盘清理指南&#xff0c;清理出30G起&#xff0c;超详细总结&am…

Docker:Docker Compose(补充三)

Docker&#xff1a;Docker Compose 1. Docker Compose 批量管理容器的工具 1. Docker Compose 批量管理容器的工具 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过一个 YAML 文件来配置应用服务&#xff0c;它允许用户编排、组合和配置多个容器的部署…

lightRAG 论文阅读笔记

论文原文 https://arxiv.org/pdf/2410.05779v1 这里我先说一下自己的感受&#xff0c;这篇论文整体看下来&#xff0c;没有太多惊艳的地方。核心就是利用知识图谱&#xff0c;通过模型对文档抽取实体和关系。 然后基于此来构建查询。核心问题还是在解决知识之间的连接问题。 论…

Visual studio的AI插件-通义灵码

通义灵码 TONGYI Lingma 兼容 Visual Studio、Visual Studio Code、JetBrains IDEs 等主流 IDE&#xff1b;支持 Java、Python、Go、C/C、C#、JavaScript、TypeScript、PHP、Ruby、Rust、Scala 等主流编程语言。 安装 打开扩展管理器&#xff0c;搜送“TONGYI Lingma”&…

shutil 文件拷贝copy - python 实现

DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” -------------------------------------------------------------…

attack xv6

思路 被这个实验折磨了两天&#xff0c;可能是2024新出的一个实验内容&#xff0c;网上资料少&#xff0c;参考了一篇仅有的博客&#xff0c;吭哧吭哧分析出来了个大概吧…在此记录一下&#xff0c;以便帮助有需要的人。 attack xv6的ans只有几行代码&#xff0c;根据实验描述…

Flink CDC实时同步mysql数据

官方参考资料&#xff1a; https://nightlies.apache.org/flink/flink-cdc-docs-master/zh/docs/connectors/flink-sources/mysql-cdc/ Apache Flink 的 Change Data Capture (CDC) 是一种用于捕获数据库变化&#xff08;如插入、更新和删除操作&#xff09;的技术。Flink CDC…

eclipse 如何设置项目、不同类型文件的 utf8 编码

编码问题一直是软件开发中让人头疼的小细节&#xff0c;尤其是团队协作中&#xff0c;若编码格式不统一&#xff0c;乱码问题便会频繁出现。那么如何在 Eclipse 中统一设置项目和文件的 UTF-8 编码&#xff0c;避免因编码问题造成不必要的困扰呢&#xff1f;今天&#xff0c;我…

Unity中触发器Trigger无法被射线检测到的问题

今天在做项目的时候发现,同一个物体,当他是碰撞器的时候,可以被射线检测到. 但是当他变成触发器的时候,射线就检测不到了??? 本来以为就是这样的,但是查了资料发现并没有这样的限制,触发器也是可以正常被射线检测的 到处查资料都没有发现问题,后来发现是下面这个设置不知道…

第一个AJAX调用XMLHttpRequest

第一个AJAX调用XMLHttpRequest 创建对象&#xff0c;用于浏览器和服务器的通信&#xff0c;不需要刷新浏览器 const request new XMLHttpRequest();通过GET请求方式在API中请求数据 request.open(GET, https://restcountries.com/v3.1/name/Russia);注&#xff1a;我这里的…

群落生态学研究进展】Hmsc包开展单物种和多物种分析的技术细节及Hmsc包的实际应用

联合物种分布模型&#xff08;Joint Species Distribution Modelling&#xff0c;JSDM&#xff09;在生态学领域&#xff0c;特别是群落生态学中发展最为迅速&#xff0c;它在分析和解读群落生态数据的革命性和独特视角使其受到广大国内外学者的关注。在学界不同研究团队研发出…

如何在 Apifox 中发布多语言的 API 文档?

“API 文档是开发协作的桥梁&#xff0c;而多语言支持则让这座桥梁跨越更多的技术边界。使用 Apifox&#xff0c;不仅可以快速生成 API 文档&#xff0c;还能轻松实现多语言的支持与发布。今天&#xff0c;我们一起来探索 Apifox 在多语言文档发布中的最佳实践&#xff01;” …

华为云检查服务器状态

VNC方式登录云服务器正常&#xff0c;但无法通过远程桌面连接方式登录云服务器时&#xff0c;推荐您按照以下思路排查问题。 以下排查思路根据原因的出现概率进行排序&#xff0c;建议您从高频率原因往低频率原因排查&#xff0c;从而帮助您快速找到问题的原因。 如果解决完某…

leetcode212. 单词搜索 II

给定一个 m x n 二维字符网格 board 和一个单词&#xff08;字符串&#xff09;列表 words&#xff0c; 返回所有二维网格上的单词 。 单词必须按照字母顺序&#xff0c;通过 相邻的单元格 内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一…

无缝钢管内表面缺陷检测的自强化感知协调网络

摘要 无缝钢管是重要的工业材料。然而&#xff0c;无缝钢管中的内表面缺陷检测具有挑战性&#xff0c;并且会显著影响无缝钢管的性能和寿命。现有的检测方法是劳动强度大的&#xff0c;并且检测结果的可视化程度低。因此&#xff0c;本文提出了一种新型的管道内表面缺陷螺旋式全…