当前位置: 首页 > article >正文

【LeetCode Hot100 子串】和为 k 的子数组、滑动窗口最大值、最小覆盖子串

子串

    • 1. 和为 k 的子数组
      • 题目描述
      • 解题思路
        • 主要思路
        • 步骤
      • 时间复杂度与空间复杂度
      • 代码实现
    • 2. 滑动窗口最大值
      • 题目描述
      • 解题思路
        • 双端队列的原理:
        • 优化步骤:
      • Java实现
    • 3. 最小覆盖子串
      • 题目描述
      • 解题思路
        • 滑动窗口的基本思路:
        • 具体步骤:
        • 算法的关键点:
      • Java实现

1. 和为 k 的子数组

题目描述

给定一个整数数组 nums 和一个整数 k,你需要在数组中找到连续子数组的个数,使得这些子数组的和等于 k

解题思路

我们可以通过 前缀和 的方法来高效解决这个问题,结合 哈希表 来记录每个前缀和出现的次数,从而迅速计算出满足条件的子数组。

主要思路
  1. 前缀和的定义

    • 对于数组 numsprefix[i] 表示从 nums[0]nums[i-1] 的和。也就是说,prefix[i] = nums[0] + nums[1] + ... + nums[i-1]
    • 子数组的和 nums[i..j] 可以表示为:prefix[j+1] - prefix[i]。因此,如果我们希望找到 nums[i..j] 的和为 k,那么只需要满足 prefix[j+1] - prefix[i] = k
  2. 如何利用哈希表

    • 在遍历数组时,我们可以计算当前的前缀和 pre
    • 然后,我们通过 map.containsKey(pre - k) 来判断是否存在一个前缀和为 pre - k 的位置,这样就找到了一个子数组和为 k
    • 我们还需要维护一个哈希表 map,其中 map.get(pre) 表示当前前缀和 pre 出现的次数。这样做是为了确保我们能够计算出所有符合条件的子数组。
  3. 核心算法

    • 初始化哈希表 map,将 0 的计数初始化为 1,因为如果前缀和刚好为 k,就意味着从数组起始位置开始的子数组和为 k
    • 遍历数组并更新前缀和,并利用哈希表记录前缀和的出现次数。
步骤
  1. 初始化

    • pre = 0 表示当前的前缀和。
    • cnt = 0 表示符合条件的子数组数量。
    • map 存储前缀和及其出现次数,初始时将 map.put(0, 1),即前缀和为 0 出现 1 次。
  2. 遍历数组

    • 对于每个元素,更新前缀和 pre
    • 检查哈希表中是否存在 pre - k,如果存在,说明从某个位置到当前位置的子数组和为 k,则将其出现次数加到 cnt 中。
    • 更新哈希表,将当前前缀和 pre 出现的次数加 1。
  3. 返回结果

    • 遍历完所有元素后,cnt 中存储的就是符合条件的子数组数量。

时间复杂度与空间复杂度

  • 时间复杂度O(n),其中 n 是数组 nums 的长度。我们只需要遍历一次数组,同时进行常数时间的哈希表操作。
  • 空间复杂度O(n),我们需要使用哈希表存储前缀和及其出现次数,最坏情况下哈希表的大小为 n

代码实现

class Solution {public int subarraySum(int[] nums, int k) {int len = nums.length;int pre = 0, cnt = 0;HashMap<Integer, Integer> map = new HashMap<>();map.put(0, 1); // 初始化,前缀和为0的有1个,这样做不会忽略掉“从数组起始位置开始的和为 k 的子数组”。for (int i = 0; i < len; i++) {pre += nums[i]; // 计算当前前缀和if (map.containsKey(pre - k)) {  // 说明从某个位置到当前位置存在连续子数组和为 kcnt = cnt + map.get(pre - k); // 增加符合条件的子数组的数量}// 更新哈希表,记录当前前缀和出现的次数map.put(pre, map.getOrDefault(pre, 0) + 1); }return cnt; // 返回符合条件的子数组数量}
}

2. 滑动窗口最大值

题目描述

给定一个整数数组 nums 和一个滑动窗口的大小 k,请你在数组中找出每个滑动窗口的最大值,并返回一个数组。

解题思路

这道题目是一个典型的滑动窗口问题。直接暴力计算每个窗口中的最大值的时间复杂度是 O(n*k),这种做法在数据量较大的情况下效率较低。因此,我们可以使用 双端队列(Deque) 来优化这一过程。

双端队列的原理:
  • 双端队列是一种支持从两端高效插入和删除的队列结构。我们可以利用它来存储数组元素的下标,并保持队列中的元素按照值的大小顺序排列。这样可以确保队列的第一个元素永远是当前窗口中的最大值。
优化步骤:

及时去掉无用数据,保证双端队列有序(当前数组>=队尾,弹出队尾;弹出队首不在窗口内的元素)

  1. 使用一个双端队列 q 来存储窗口中的元素的下标。
  2. 保证队列中的元素下标对应的值是递减的,队列的首部始终是窗口的最大值。
  3. 每次移动窗口时:
    • 入队操作:将新元素的下标加入队列,并从队列的尾部移除所有小于当前元素的值,以保证队列保持递减顺序。
    • 出队操作:如果队列头部的元素已经不再在当前窗口范围内(即超出窗口的左边界),则将其从队列中移除。
    • 记录结果:当窗口大小达到 k 时,记录当前窗口的最大值,即队列头部的元素。

Java实现

class Solution {public int[] maxSlidingWindow(int[] nums, int k) {int n = nums.length;Deque<Integer> q = new ArrayDeque<>(); // 存的是nums的下标int[] ans = new int[n - k + 1];for (int i = 0; i < n; i++) {// 1. 入队:保持队列中的元素递减while (!q.isEmpty() && nums[i] >= nums[q.getLast()]) {q.removeLast();}q.addLast(i); // 队列存的是下标// 2. 出队:如果队列的第一个元素不在窗口内,移除它if (i - q.getFirst() >= k) {q.removeFirst();}// 3. 存结果:当窗口大小达到k时,记录最大值if (i >= k - 1) {ans[i - k + 1] = nums[q.getFirst()];}}return ans;}
}

3. 最小覆盖子串

题目描述

给定字符串 s 和字符串 t,找到 s 中包含 t 中所有字符的最小子串。如果 s 中没有包含 t 中所有字符的子串,则返回空字符串。

解题思路

这是一个经典的滑动窗口问题。我们需要在字符串 s 中找到一个最小的子串,该子串包含了 t 中所有字符。最初我们可以考虑暴力解法,但暴力解法会超时,因此我们需要使用 滑动窗口 技巧来优化算法。

滑动窗口的基本思路:
  1. 滑动窗口的定义:我们维护一个窗口,窗口的大小是可变的,在窗口内包含了 t 中的所有字符。
  2. 扩展窗口:从字符串 s 的开始位置开始扩展窗口,逐步包含 t 中的字符。
  3. 收缩窗口:当窗口已经包含了 t 中的所有字符时,尝试缩小窗口的大小,以找到更小的符合条件的子串。
  4. 窗口合法性:当窗口内包含所有 t 中的字符时,窗口是合法的。
具体步骤:
  1. 使用两个指针 leftright 表示滑动窗口的左右边界,初始化时都指向字符串 s 的开头。
  2. 使用两个哈希表 cntTcntS 来记录 t 中字符的出现频率和当前窗口中字符的出现频率。
  3. 当窗口包含 t 中的所有字符时,尝试缩小窗口的左边界。
  4. 在每次扩展和收缩窗口时,更新当前的最小子串。
算法的关键点:
  • 记录 t 中所有字符的频率。
  • 使用两个指针维护滑动窗口。
  • 记录窗口内字符的频率并与 t 中的字符频率进行比较。

Java实现

class Solution {public String minWindow(String s, String t) {int ansLeft = -1;int m = s.length();int ansRight = m;// 记录t的字符出现的次数Map<Character, Integer> cntT = new HashMap<>();for (char c : t.toCharArray()) {cntT.put(c, cntT.getOrDefault(c, 0) + 1);}// 记录s的字符出现的次数Map<Character, Integer> cntS = new HashMap<>();int left = 0;int formed = 0;  // 记录s和t覆盖的字符的个数int required = cntT.size();  // 记录t中的不同字符的个数for (int right = 0; right < m; right++) {char sr = s.charAt(right);cntS.put(sr, cntS.getOrDefault(sr, 0) + 1);// 如果s中的字符完全匹配t中的字符if (cntT.containsKey(sr) && cntS.get(sr).intValue() == cntT.get(sr).intValue()) {formed++;}// 当s子串能覆盖t的时候收缩窗口while (formed == required) {if (right - left < ansRight - ansLeft) {ansLeft = left;ansRight = right;}// 收缩窗口char leftChar = s.charAt(left);cntS.put(leftChar, cntS.get(leftChar) - 1);if (cntT.containsKey(leftChar) && cntS.get(leftChar).intValue() < cntT.get(leftChar).intValue()) {formed--;}left++;}}return ansLeft < 0 ? "" : s.substring(ansLeft, ansRight + 1); // 左闭右开}
}

相关文章:

【LeetCode Hot100 子串】和为 k 的子数组、滑动窗口最大值、最小覆盖子串

子串 1. 和为 k 的子数组题目描述解题思路主要思路步骤 时间复杂度与空间复杂度代码实现 2. 滑动窗口最大值题目描述解题思路双端队列的原理&#xff1a;优化步骤&#xff1a; Java实现 3. 最小覆盖子串题目描述解题思路滑动窗口的基本思路&#xff1a;具体步骤&#xff1a;算法…...

【kafka系列】Kafka如何实现高吞吐量?

目录 1. 生产者端优化 核心机制&#xff1a; 关键参数&#xff1a; 2. Broker端优化 核心机制&#xff1a; 关键源码逻辑&#xff1a; 3. 消费者端优化 核心机制&#xff1a; 关键参数&#xff1a; 全链路优化流程 吞吐量瓶颈与调优 总结 Kafka的高吞吐能力源于其生…...

foobar2000设置DSP使用教程及软件推荐

foobar2000安卓中文版&#xff1a;一款高品质手机音频播放器 foobar2000安卓中文版是一款备受好评的高品质手机音频播放器。 几乎支持所有的音频格式&#xff0c;包括 MP3、MP4、AAC、CD 音频等。不论是经典老歌还是最新的流行音乐&#xff0c;foobar2000都能完美播放。除此之…...

【JAVA工程师从0开始学AI】,第四步:闭包与高阶函数——用Python的“魔法函数“重构Java思维

副标题&#xff1a;当严谨的Java遇上"七十二变"的Python函数式编程 历经变量战争、语法迷雾、函数对决&#xff0c;此刻我们将踏入Python最迷人的领域——函数式编程。当Java工程师还在用接口和匿名类实现回调时&#xff0c;Python的闭包已化身"智能机器人"…...

【R语言】回归分析与判别分析

一、线性回归分析 1、lm()函数 lm()函数是用于拟合线性模型&#xff08;Linear Models&#xff09;的主要函数。线性模型是一种统计方法&#xff0c;用于描述一个或多个自变量&#xff08;预测变量、解释变量&#xff09;与因变量&#xff08;响应变量&#xff09;之间的关系…...

AllData数据中台核心菜单十三:数据湖平台

&#x1f525;&#x1f525; AllData大数据产品是可定义数据中台&#xff0c;以数据平台为底座&#xff0c;以数据中台为桥梁&#xff0c;以机器学习平台为中层框架&#xff0c;以大模型应用为上游产品&#xff0c;提供全链路数字化解决方案。 ✨奥零数据科技官网&#xff1a;…...

Spring Cloud Gateway中断言路由和过滤器的使用

一&#xff0c;Gateway概念 Spring Cloud Gateway&#xff08;简称 Gateway&#xff09;是一个基于 Spring WebFlux 的 API 网关解决方案&#xff0c;旨在为微服务架构中的客户端提供路由、负载均衡、认证、限流、监控等功能。它作为微服务架构中的流量入口&#xff0c;通常位…...

Android 13 上通过修改 AOSP 拦截 SystemUI 音量调节事件

定位关键代码SystemUI 的音量调节逻辑主要集中在以下类中: VolumeDialogController.java:负责与 AudioService 交互。 VolumeDialogImpl.java:处理 UI 交互事件(如按钮点击)。 PhoneWindowManager.java:处理物理按键事件(如音量键)。 拦截音量调节事件 以 VolumeDialog…...

AcWing 798. 差分矩阵

题目来源&#xff1a; 找不到页面 - AcWing 题目内容&#xff1a; 输入一个 n 行 m 列的整数矩阵&#xff0c;再输入 q 个操作&#xff0c;每个操作包含五个整数 x1,y1,x2,y2,c&#xff0c;其中 (x1,y1) 和 (x2,y2)表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将…...

Docker 部署 MySQL 8 详细图文教程

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; GitCode︱ Gitee ︱ Github &#x1f496; 欢迎点赞 &#x1f44d; 收藏 ⭐评论 …...

【Python】模式匹配 match语句详解(仅在Python 3.10及以上版本中可用)

文章目录 模式匹配 match语句(仅在 Python 3.10及以上版本 中可用)1. 基本语法2. 基本匹配操作2.1 匹配常量2.2 匹配变量2.3 匹配元组2.4 匹配列表2.5 匹配字典2.6 条件匹配 3. 应用场景 模式匹配 match语句(仅在 Python 3.10及以上版本 中可用) Python 3.10 及以上版本中才引…...

vscode ESP32配置

一、自定义文件组件使用xxxx.c xxxx.h 1: 控制端工程目录创建组件文件夹 》 idf.py -C components create-component User_led 2: 定义组件如果引用指定外部依赖库,当前文件的cmakelists.txt 添加 REQUIRES driver idf_component_register(SRCS "uesr_led.c"INCLU…...

idea 2019.3常用插件

idea 2019.3常用插件 文档 idea 2019.3常用插件idea 2023.3.7常用插件 idea 2019.3常用插件 插件名称插件版本说明1AceJump3.5.9AceJump允许您快速将插入符号导航到编辑器中可见的任何位置。只需按“ctrl&#xff1b;”&#xff0c;键入一个字符&#xff0c;然后在Ace Jump…...

全单模矩阵及其在分支定价算法中的应用

全单模矩阵及其在分支定价算法中的应用 目录 全单模矩阵的定义与特性全单模矩阵的判定方法全单模矩阵在优化中的核心价值分支定价算法与矩阵单模性的关系非全单模问题的挑战与系统解决方案总结与工程实践建议 1. 全单模矩阵的定义与特性 关键定义 单模矩阵&#xff08;Unimo…...

算法与数据结构(最小栈)

题目 思路 为了返回栈中的最小元素&#xff0c;我们需要额外维护一个辅助栈 min_stack&#xff0c;它的作用是记录当前栈中的最小值。 min_stack的作用&#xff1a; min_stack的栈顶元素始终是当前栈 st 中的最小值。 每当st中压入一个新元素时&#xff0c;如果这个元素小于等…...

KVM设置端口转发

20250217 - 概述 在ubuntu下进行虚拟机开发环境设置&#xff0c;希望外网也能够进行访问&#xff0c; 一开始希望通过桥接的方式来实现&#xff0c;但是发现有些不适配&#xff1b;所以最后使用了 NAT转发的形式。 一开始看的文章[1]&#xff0c;在设置路由转发之后&#xf…...

openCV中如何实现滤波

图像滤波用于去除噪声和图像平滑&#xff0c;OpenCV 提供了多种滤波器&#xff1a; 1.1. 均值滤波&#xff1a; import cv2# 读取图像 image cv2.imread("example.jpg")# 均值滤波 blurred_image cv2.blur(image, (5, 5)) # (5, 5) 是滤波核的大小 滤波核大小的…...

清影2.0(AI视频生成)技术浅析(二):自然语言处理

清影2.0(AI视频生成)中的自然语言处理(NLP)技术是其核心组件之一,负责将用户输入的自然语言文本转化为机器可以理解的语义表示,从而指导后续的视频生成过程。 一、基本原理 1. 目标 清影2.0的NLP技术旨在将用户输入的自然语言文本转化为机器可以理解的语义表示,从而指…...

五十天精通硬件设计第32天-S参数

系列文章传送门 50天精通硬件设计第一天-总体规划-CSDN博客 目录 1. S参数基础 2. S参数在信号完整性中的作用 3. 单端 vs. 差分S参数 4. S参数的关键特性 5. S参数的获取与使用 6. S参数分析中的常见问题 7. 实际案例:PCIe通道分析 8. 工具推荐 总结 信号完整性中…...

AI在网络安全中的应用:构建智能防护体系

AI在网络安全中的应用:构建智能防护体系 大家好,我是你们熟悉的人工智能与Python领域自媒体创作者Echo_Wish。今天我们来聊聊如何用AI技术提升网络安全水平。随着互联网的发展和数字化转型,网络安全威胁日益增多,传统的安全防护手段已经难以应对复杂多变的网络攻击。AI技术…...

【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十七节】

ISO 14229-1:2023 UDS诊断服务测试用例全解析&#xff08;InputOutputControl_0x2F服务&#xff09; 作者&#xff1a;车端域控测试工程师 更新日期&#xff1a;2025年02月14日 关键词&#xff1a;UDS协议、0x2F服务、输入输出控制、ISO 14229-1:2023、ECU测试 一、服务功能概…...

2025 BabitMF 第一期开源有奖活动正式开启 !

为了促进开源社区的交流与成长&#xff0c;字节跳动开源的多媒体处理框架 BabitMF &#xff08;GitHub - BabitMF/bmf: Cross-platform, customizable multimedia/video processing framework. With strong GPU acceleration, heterogeneous design, multi-language support, e…...

Docker 安装和配置 Nginx 详细图文教程

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; GitCode︱ Gitee ︱ Github &#x1f496; 欢迎点赞 &#x1f44d; 收藏 ⭐评论 …...

链表和list

链表和list ‍ ​ ​ ​ ​ ​ ​ ​ ​ ​ 算法题中的经典操作&#xff1a;用空间代替时间​ ​ ​ ​ 双链表头插顺序&#xff1a; 1.先修改新结点的左右指针 2.然后修改结点y的左指针 3.最后修改哨兵位的右指针 双链表在任意位置&#xff08;p&#xff09;之后插入…...

深度学习机器学习:常用激活函数(activation function)详解

目录 Sigmoid Function ReLU&#xff08;Rectified Linear Unit&#xff09; LeakyReLU&#xff08;Leaky Rectified Linear Unit&#xff09; ClippedReLU&#xff08;Clipped Rectified Linear Unit&#xff09; PRelu&#xff08;Parametric ReLU&#xff09; Tanh&am…...

AIGC图生视频保姆级教程

一、AI文生图高阶技巧 推荐工具 ▸ MidJourney&#xff08;艺术感最强&#xff09; ▸ DALLE 3&#xff08;与ChatGPT深度联动&#xff09; ▸ Leonardo.ai&#xff08;精细化参数控制&#xff09; 核心策略 提示词架构&#xff1a; [主体描述][环境氛围][镜头语言][风格参数…...

【对比】Pandas 和 Polars 的区别

Pandas vs Polars 对比表 特性PandasPolars开发语言Python&#xff08;Cython 实现核心部分&#xff09;Rust&#xff08;高性能系统编程语言&#xff09;性能较慢&#xff0c;尤其在大数据集上&#xff08;内存占用高&#xff0c;计算效率低&#xff09;极快&#xff0c;利用…...

C# 鼠标点击ToolStripStatuslabel 在线修改Text属性并存储加载显示Text属性

在实际项目中为方便了解视觉软件的使用性&#xff0c;可能需要添加一些小而稍微实用的功能:一个StipStatus控件上的Label按钮属性Text需要修改并保存&#xff0c;软件重启后能够自动加载修改后的属性名。 定义变量 public static string controlsText System.Windows.Forms.A…...

下载安装运行测试开源vision-language-action(VLA)模型OpenVLA

1. 安装 项目官网OpenVLA 首先按照官网提示的以下代码&#xff0c;执行创建环境->安装最小依赖->git克隆项目等 # Create and activate conda environment conda create -n openvla python3.10 -y conda activate openvla# Install PyTorch. Below is a sample comma…...

PyQt6/PySide6 的 SQL 数据库操作(QtSql)

一、核心组件架构 1.1 QtSql模块构成 QSqlDatabase&#xff1a;数据库连接管理&#xff08;支持连接池&#xff09;QSqlQuery&#xff1a;SQL语句执行与结果遍历QSqlTableModel&#xff1a;可编辑的表格数据模型QSqlQueryModel&#xff1a;只读查询结果模型QSqlRelationalTab…...