【LeetCode】力扣刷题热题100道(21-25题)附源码 接雨水 合并区间 字母异位词 滑动窗口 覆盖子串(C++)

目录

1.接雨水

2.合井区间

3.找到字符串中所有字母异位词

4.滑动窗口最大值

5.最小覆盖子串


1.接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

代码如下所示:

class Solution {
public:int trap(vector<int>& height) {int n = height.size();if (n == 0) return 0;int left = 0, right = n - 1;int left_max = 0, right_max = 0;int water = 0;while (left < right) {if (height[left] < height[right]) {if (height[left] >= left_max) {left_max = height[left]; // 更新左侧最大高度} else {water += left_max - height[left]; // 累加雨水}++left; // 左指针右移} else {if (height[right] >= right_max) {right_max = height[right]; // 更新右侧最大高度} else {water += right_max - height[right]; // 累加雨水}--right; // 右指针左移}}return water;}
};

利用两个指针分别从数组的两端向中间遍历。

同时维护两个变量:

left_max:从左侧当前最大高度。

right_max:从右侧当前最大高度。

计算能接的雨水:

如果 height[left] 小于等于 height[right],则 left 所在位置的最大雨水由 left_max - height[left] 决定,更新左指针。

如果 height[right] 小于 height[left],则 right 所在位置的最大雨水由 right_max - height[right] 决定,更新右指针。

继续移动指针,直到 left == right。

2.合井区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {// 按区间的起点进行排序sort(intervals.begin(), intervals.end());vector<vector<int>> merged;for (const auto& interval : intervals) {// 如果结果数组为空,或者当前区间与上一个区间不重叠,直接添加if (merged.empty() || merged.back()[1] < interval[0]) {merged.push_back(interval);} else {// 如果当前区间与上一个区间重叠,合并它们merged.back()[1] = max(merged.back()[1], interval[1]);}}return merged;}
};

将区间集合中所有重叠的区间合并成不重叠的区间集合。首先,通过对区间集合按起点升序排序,确保后续处理的区间是按顺序排列的;接着,使用一个结果数组 merged 存储最终的非重叠区间。遍历排序后的区间集合时,如果当前区间与结果数组最后一个区间不重叠,则直接将其加入结果数组;如果重叠,则通过更新终点为两者的较大值来合并区间。这种方法充分利用排序和遍历的性质,以线性方式逐步合并区间,最终返回一个不重叠的区间集合。

3.找到字符串中所有字母异位词

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

字母异位词,字母异位词是通过重新排列不同单词或短语的字母而形成的单词或短语,并使用所有原字母一次。

class Solution {
public:vector<int> findAnagrams(string s, string p) {vector<int> result;if (s.size() < p.size()) return result;// 记录 p 的字符频率vector<int> pCount(26, 0), sCount(26, 0);for (char c : p) {pCount[c - 'a']++;}// 初始化 s 中的滑动窗口for (int i = 0; i < p.size(); ++i) {sCount[s[i] - 'a']++;}// 检查初始窗口是否匹配if (sCount == pCount) {result.push_back(0);}// 滑动窗口遍历 sfor (int i = p.size(); i < s.size(); ++i) {// 添加右侧字符sCount[s[i] - 'a']++;// 移除左侧字符sCount[s[i - p.size()] - 'a']--;// 检查当前窗口是否匹配if (sCount == pCount) {result.push_back(i - p.size() + 1);}}return result;}
};

使用一个固定大小的窗口遍历字符串 s。

在每一步中,检查窗口内的字符计数是否与字符串 p 的字符计数匹配。

如果匹配,则记录当前窗口的起始索引。

使用两个计数器来高效地更新滑动窗口,避免重复计算。

字符计数:pCount 和 sCount 用于存储 p 和当前窗口的字符频率。每个频率数组大小为 26(对应字母 a-z)。

初始窗口设置:初始化 sCount 为 s 中前 p.size() 个字符的频率。

滑动窗口更新:

每次窗口向右滑动一个字符。

添加新字符到窗口中,同时移除窗口最左边的字符。窗口匹配检查:每次更新窗口后检查 sCount 是否等于 pCount,相等时记录窗口的起始索引。

4.滑动窗口最大值

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回 滑动窗口中的最大值 

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {vector<int> result;deque<int> dq; // 双端队列,用来存储窗口中元素的索引for (int i = 0; i < nums.size(); ++i) {// 移除不在窗口范围内的元素if (!dq.empty() && dq.front() < i - k + 1) {dq.pop_front();}// 移除所有小于当前元素的值,它们不可能成为窗口的最大值while (!dq.empty() && nums[dq.back()] < nums[i]) {dq.pop_back();}// 将当前元素的索引加入队列dq.push_back(i);// 窗口形成后(即 i >= k - 1),记录窗口的最大值if (i >= k - 1) {result.push_back(nums[dq.front()]);}}return result;}
};

双端队列维护窗口最大值:

双端队列存储的是元素的索引,而不是值。

保证队列中索引对应的值是递减的,从而队列头部始终是窗口内的最大值。

窗口的更新:

移除队列中不在当前窗口范围内的元素。

移除队列中所有小于当前值的元素,因为它们不可能成为当前窗口的最大值。

记录最大值:

每次移动窗口时,将队列头部的值(即当前窗口的最大值)加入结果。

双端队列的性质:

队列中的元素从头到尾递减。

队列头部始终是当前窗口的最大值。

滑动窗口逻辑:

当窗口左边界超出队列中最左边的索引时,移除队列头部。

插入新元素之前,移除队列中所有小于当前值的元素。

结果记录:当窗口的右边界到达 k−1k - 1k−1 或之后时,窗口形成,记录最大值。

5.最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

注意:对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。

class Solution {
public:string minWindow(string s, string t) {unordered_map<char, int> need, window;for (char c : t) need[c]++;int left = 0, right = 0;  // 滑动窗口的左右指针int valid = 0;           // 当前窗口中满足要求的字符数int start = 0, minLen = INT_MAX; // 最小子串的起始位置和长度while (right < s.size()) {char c = s[right]; // 即将移入窗口的字符right++;           // 扩大窗口// 如果当前字符是目标字符之一,则更新窗口内的数据if (need.count(c)) {window[c]++;if (window[c] == need[c]) valid++;}// 判断是否需要收缩窗口while (valid == need.size()) {// 更新最小子串if (right - left < minLen) {start = left;minLen = right - left;}char d = s[left]; // 即将移出窗口的字符left++;           // 缩小窗口// 更新窗口内的数据if (need.count(d)) {if (window[d] == need[d]) valid--;window[d]--;}}}// 如果找到了符合条件的子串,返回它;否则返回空字符串return minLen == INT_MAX ? "" : s.substr(start, minLen);}
};

使用两个指针表示滑动窗口的起始和结束位置。

用一个哈希表(need)记录字符串 t 中每个字符的频率,用另一个哈希表(window)记录当前窗口中每个字符的频率。

遍历字符串 s,调整窗口的大小:

当窗口中的字符已满足 t 的要求时,尝试收缩窗口。

每次收缩时检查窗口长度,并更新最小长度和起始位置。如果遍历完成后没有找到符合条件的子串,返回空字符串。

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

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

相关文章

慧集通(DataLinkX)iPaaS集成平台-智能体(Agent)API

功能简介&#xff1a; 该功能下主要是用来管理集成平台对外开放接口得管控以及调用日志信息得查看操作&#xff0c;并支持日志得重放等操作&#xff1b;注&#xff1a;所有触发类单据得日志也可以在此查看(如使用数据触发组件自动触发流程得日志信息) 1.第三方调用接口类日志查…

HTB:Bank[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 提取出靶机TCP开放端口 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 使用curl对域名进行访问…

创建基本的 Electron 应用项目的详细步骤

创建一个基本的 Electron 应用项目的详细步骤。我们将从安装 Node.js 开始&#xff0c;然后创建项目文件夹并初始化 Electron 项目。 1. 安装 Node.js 首先&#xff0c;确保你已经安装了 Node.js 和 npm。你可以在终端中运行以下命令来检查是否已经安装&#xff1a; node -v…

TDengine + MQTT :车联网时序数据库如何高效接入

现代新能源汽车&#xff0c;作为一种内部系统极为复杂的交通工具&#xff0c;配备了大量传感器、导航设备、应用软件&#xff0c;这些传感器产生的数据都需要上报到车联网平台当中。对于这些车辆的状态数据&#xff08;如车速、发动机转速等&#xff09;、位置数据&#xff08;…

2. Scala 高阶语法之集合与元组

背景 上一章简单介绍了scala是什么&#xff0c;以及scala的基础用法&#xff0c;本文介绍scala的高阶语法&#xff0c;希望看完本章之后&#xff0c;读者能体会到scala和java的明显区别&#xff0c;以及scala的强大之处。 1. 数组 Scala中提供了一种数据结构-数组&#xff0…

初学STM32 --- USMART

目录 USMART简介 USMART主要特点&#xff1a; USMART原理 USMART组成&#xff1a; USMART 的实现流程简单概括 USMART扫描函数&#xff1a; USMART系统命令 USMART移植 USMART简介 USMART是一个串口调试组件&#xff0c;可以大大提高代码调试效率&#xff01; USMART主…

SQL编程语言

第一章 1. 数据库是长期储存在计算机内&#xff0c;由专门的数据管理软件(数据库管理系统)&#xff0c;进行统一组织和管理控制的大量数据的集合。 2.数据库的基本特点不包括可以快速检索。 3. 数据管理技术的发展经历了&#xff1a;人工管理阶段、文件系统阶段、数据库系统阶…

机器学习周报-ModernTCN文献阅读

文章目录 摘要Abstract 0 提升有效感受野&#xff08;ERF&#xff09;1 相关知识1.1 标准卷积1.2 深度分离卷积&#xff08;Depthwise Convolution&#xff0c;DWConv&#xff09;1.3 逐点卷积&#xff08;Pointwise Convolution&#xff0c;PWConv&#xff09;1.4 组卷积(Grou…

《OpenCV计算机视觉实战项目》——银行卡号识别

文章目录 项目任务及要求项目实现思路项目实现及代码导入模块设置参数对模版图像中数字的定位处理银行卡的图像处理读取输入图像&#xff0c;预处理找到数字边框使用模版匹配&#xff0c;计算匹配得分 画出并打印结果 项目任务及要求 任务书&#xff1a; 要为某家银行设计一套…

【LeetCode: 560. 和为 K 的子数组 + 前缀和 + 哈希表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Tableau数据可视化与仪表盘搭建-可视化原则及BI仪表盘搭建

目录 可视化原则 BI仪表盘搭建 仪表盘搭建原则 明确仪表盘主题 仪表盘主题拆解 开发设计工作表 经营情况总览&#xff1a;突出显示的文字 经营数据详情&#xff1a;表格 每日营收数据&#xff1a;多轴折线图 每日流量数据&#xff1a;双轴组合图 新老客占比&#xf…

vue2日历组件

这个代码可以直接运行&#xff0c;未防止有组件库没安装&#xff0c;将组件库的代码&#xff0c;转成文字了 vue页面 <template><div class"about"><div style"height: 450px; width: 400px"><div style"height: 100%; overflo…

交响曲-24-3-单细胞CNV分析及聚类

CNV概述 小于1kb是常见的插入、移位、缺失等的变异 人体内包含<10% 的正常CNV&#xff0c;我们的染色体数是两倍体&#xff0c;正常情况下&#xff0c;只有一条染色体表达&#xff0c;另一条沉默&#xff0c;当表达的那条染色体发生CNV之后&#xff0c;表达数量就会成倍增加…

UDP -- 简易聊天室

目录 gitee&#xff08;内有详细代码&#xff09; 图解 MessageRoute.hpp UdpClient.hpp UdpServer.hpp Main.hpp 运行结果&#xff08;本地通信&#xff09; 如何分开对话显示&#xff1f; gitee&#xff08;内有详细代码&#xff09; chat_room zihuixie/Linux_Lear…

电影动画shader解析与实现

着色器代码解析 大家好&#xff01;我是 [数擎AI]&#xff0c;一位热爱探索新技术的前端开发者&#xff0c;在这里分享前端和Web3D、AI技术的干货与实战经验。如果你对技术有热情&#xff0c;欢迎关注我的文章&#xff0c;我们一起成长、进步&#xff01; 开发领域&#xff1a;…

【FlutterDart】 拖动边界线改变列宽类似 vscode 那种拖动改变编辑框窗口大小(11 /100)

【Flutter&Dart】 拖动改变 widget 的窗口尺寸大小GestureDetector&#xff5e;简单实现&#xff08;10 /100&#xff09; 【Flutter&Dart】 拖动边界线改变列宽并且有边界高亮和鼠标效果&#xff08;12 /100&#xff09; 上效果&#xff1a; 这个在知乎里找到的效果&…

【Rust自学】11.1. 编写和运行测试

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 11.1.1. 什么是测试 在Rust里一个测试就是一个函数&#xff0c;它被用于验证非测试代码的功能是否和预期一致。 在一个测试的函数体里通…

数据分析思维(八):分析方法——RFM分析方法

数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python&#xff0c;更重要的是数据分析思维。没有数据分析思维和业务知识&#xff0c;就算拿到一堆数据&#xff0c;也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》&#xff0c;本文内容就是提取…

57. Three.js案例-创建一个带有聚光灯和旋转立方体的3D场景

57. Three.js案例-创建一个带有聚光灯和旋转立方体的3D场景 实现效果 该案例实现了使用Three.js创建一个带有聚光灯和旋转立方体的3D场景。 知识点 WebGLRenderer&#xff08;WebGL渲染器&#xff09; THREE.WebGLRenderer 是 Three.js 中用于将场景渲染为 WebGL 内容的核…

Idea-离线安装SonarLint插件地址

地址&#xff1a; SonarQube for IDE - IntelliJ IDEs Plugin | Marketplace 选择Install Plugin from Disk..&#xff0c;选中下载好的插件&#xff0c;然后重启idea