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

news2025/1/10 19:14:32

目录

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);
        }
 
        // 滑动窗口遍历 s
        for (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.coloradmin.cn/o/2274505.html

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

相关文章

01-51单片机LED与独立按键

一、单片机概述 注意&#xff1a;个人学习笔记&#xff0c;里面涉及到的C语言和进程转换相关的知识在C语言部分已经写了&#xff0c;这里是默认都会的状态学习单片机。 1.什么是单片机 单片机&#xff0c;英文Micro Controller Unit&#xff0c;简称MCU。其内部集成了CPU、R…

Linux内核编程(二十一)USB应用及驱动开发

一、基础知识 1. USB接口是什么&#xff1f; USB接口&#xff08;Universal Serial Bus&#xff09;是一种通用串行总线&#xff0c;广泛使用的接口标准&#xff0c;主要用于连接计算机与外围设备&#xff08;如键盘、鼠标、打印机、存储设备等&#xff09;之间的数据传输和电…

ModelScope创空间使用

文章目录 前言 一、ModelScope是什么&#xff1f; 二、使用步骤 1.注册ModelScope 2.新建创空间 3.创空间基本说明 4.部署创空间 5.访问创空间 三、其他补充说明 总结 前言 随着AI大模型的应用越来越广泛&#xff0c;模型应用部署的需求也越来越多&#xff0c;包括h…

记1(监督学习+一元线性回归

目录 1、基础概念2、一元线性回归 1、基础概念 机器学习&#xff08;Machine Learning&#xff09;&#xff1a;通过学习算法从数据中学习模型的过程 例如从“房价y~面积x”的关系中学习&#xff1a; 建立模型&#xff1a;ywxb 学习模型&#xff1a;确定w&#xff0c;b&#x…

服务器双网卡NCCL通过交换机通信

1、NCCL变量设置 export CUDA_DEVICE_MAX_CONNECTIONS1 export NCCL_SOCKET_IFNAMEeno2 export NCCL_IB_DISABLE0 #export NCCL_NETIB export NCCL_IB_HCAmlx5_0,mlx5_1 export NCCL_IB_GID_INDEX3 export NCCL_DEBUGINFOGPUS_PER_NODE4MASTER_ADDR192.168.1.2 MASTER_PORT600…

PySide6 Qt for Python Qt Quick参考网址

Qt QML BOOK&#xff1a; 《Qt for Python》 -Building an Application https://www.qt.io/product/qt6/qml-book/ch19-python-build-app#signals-and-slots Qt for Python&#xff1a;与C版本的差异即BUG处理&#xff08;常见的DLL文件确实的问题等&#xff09; Qt for Pyt…

NineData云原生智能数据管理平台新功能发布|2024年12月版

本月发布 7 项更新&#xff0c;其中重点发布 2 项、功能优化 5 项。 重点发布 数据库 Devops - Oracle 非表对象支持可视化创建与管理 Oracle 非表对象&#xff0c;包括视图&#xff08;View&#xff09;、包&#xff08;Package&#xff09;、存储过程&#xff08;Procedur…

【Elasticsearch7.11】postman批量导入少量数据

JSON 文件内的数据格式&#xff0c;json文件数据条数不要过多&#xff0c;会请求参数过大&#xff0c;最好控制再10000以内。 {"index":{"_id":"baec07466732902d22a24ba01ff09751"}} {"uuid":"baec07466732902d22a24ba01ff0975…

用Kimi做研究:准实验设计的智能解决方案

目录 1.研究策略设计 2.过程框架设计 3.背景变量 4.细节设计 准实验设计是一种介于实验与观察研究之间的研究方法&#xff0c;准实验设计是在无法完全控制实验条件的情况下进行因果关系的探索。与传统实验设计相比&#xff0c;准实验设计不具备随机分配实验对象到各处理组的…

零基础入门Erlang

1.Erlang介绍 Index - Erlang/OTP Erlang是一种通用的面向并发的编程语言 Erlang是一个结构化&#xff0c;动态类型编程语言&#xff0c;内建并行计算支持 使用Erlang来编写分布式应用要简单的多&#xff0c;因为它的分布式机制是透明的 1.1 为什么选择Erlang 需要处理大量…

JavaWeb开发(九)JSP技术

1. JavaWeb JSP技术 1.1. JSP简介 1.1.1. 什么是JSP JSP全名为Java Server Page 是为了简化servlet的工作而出现的替代品。在JSP中java代码与HTML共同存在&#xff0c;其中HTML代码用于展示静态的内容&#xff0c;java代码用来展示动态的内容。 1.1.2. 为什么出现JSP技术 19…

鸿蒙UI开发——Toast即时提示框的使用

1、概 述 Toast提示又称即时反馈&#xff0c;是一种临时性的消息提示框&#xff0c;用于向用户显示简短的操作反馈或状态信息。它通常在屏幕的底部或顶部短暂弹出&#xff0c;随后在一段时间后自动消失。即时反馈的主要目的是提供简洁、不打扰的信息反馈&#xff0c;避免干扰用…

基于Spring Boot的海滨体育馆管理系统的设计与实现

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的海滨体育馆管理系统的设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 宠物医院…

【UE5 C++课程系列笔记】24——多线程基础——Async

目录 概念 Async函数应用案例 概念 Async 函数的原型如下 template<typename TFunction> auto Async(EAsyncExecution::Type ExecutionType, TFunction&& Function) -> decltype(Function); Async 函数是一个模板函数&#xff0c;接受两个主要参数&#x…

【环境搭建】Metersphere v2.x 容器部署教程踩坑总结

前言 Metersphere部署过程中遇到的问题有点多&#xff0c;原因是其容器的架构蛮复杂的&#xff0c;比较容易踩坑&#xff0c;所以记录一下。 介绍 MeterSphere 是开源持续测试平台&#xff0c;遵循 GPL v3 开源许可协议&#xff0c;涵盖测试管理、接口测试、UI 测试和性能测…

RabbitMQ-SpringAMQP使用介绍

RabbitMQ 1. Spring AMQP1.1 引入依赖1.2 消息发送1.3 消息接收1.4 WorkQueue模型1.4.1 实例代码1.4.2 能者多劳1.4.3 总结 1.5交换机1.6 Fanout交换机&#xff08;广播&#xff09;1.7 Direct交换机&#xff08;订阅&#xff09;1.8 Topic交换机&#xff08;通配符订阅&#x…

Can I Use 实战指南:优化你的前端开发流程

引言 浏览器兼容性问题一直是前端开发中最令人头疼的难题。无论是新技术的支持差异&#xff0c;还是老旧浏览器的兼容需求&#xff0c;开发者常常需要花费大量时间解决这些问题。而 Can I Use 正是为此而生的前端开发利器。它提供详尽的浏览器兼容性数据&#xff0c;帮助开发者…

会员制营销与门店业绩提升:以开源AI智能名片S2B2C商城小程序为例的深度剖析

摘要&#xff1a;在数字化时代&#xff0c;会员制营销已成为企业提升门店业绩、增强客户黏性的重要策略。然而&#xff0c;仅仅将会员制营销视为提升业绩的手段&#xff0c;显然过于笼统&#xff0c;缺乏精准性。本文基于“业绩客量客单回头次数”的公式&#xff0c;深入探讨了…

/src/utils/request.ts:axios 请求封装,适用于需要统一处理请求和响应的场景

文章目录 数据结构解释1. 核心功能2. 代码结构分析请求拦截器响应拦截器 3. 改进建议4. 总结 console.log(Intercepted Response:, JSON.stringify(response));{"data": {"code": 0,"msg": "成功","data": {"id":…

Ubuntu24.04安装AppImage报错AppImages require FUSE to run.

报错如下&#xff1a; 解决&#xff1a; sudo apt install libfuse2t64如果不行&#xff1a; sudo add-apt-repository universe sudo apt install libfuse2t64安装时又报错&#xff1a; [10354:0109/100149.571068:FATAL:setuid_sandbox_host.cc(158)] The SUID sandbox hel…