LeetCode 算法:找到字符串中所有字母异位词c++

原题链接🔗:找到字符串中所有字母异位词
难度:中等⭐️⭐️

题目

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

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1:
输入: s = “cbaebabacd”, p = “abc”
输出: [0,6]
解释:
起始索引等于 0 的子串是 “cba”, 它是 “abc” 的异位词。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的异位词。

示例 2:
输入: s = “abab”, p = “ab”
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 “ab”, 它是 “ab” 的异位词。
起始索引等于 1 的子串是 “ba”, 它是 “ab” 的异位词。
起始索引等于 2 的子串是 “ab”, 它是 “ab” 的异位词。

提示:
1 <= s.length, p.length <= 3 * 104
s 和 p 仅包含小写字母

题解

滑动窗口法

  1. 题解
  • 理解异位词:两个字符串是异位词,意味着它们包含相同的字符,并且每个字符出现的次数也相同,但是字符的排列顺序可以不同。

  • 滑动窗口:使用滑动窗口的方法来遍历字符串 s,窗口的大小与字符串 p 的长度相等。

  • 字符计数:使用哈希表(unordered_map)来记录字符串 p 中每个字符的出现次数。

  • 窗口内字符匹配:在滑动窗口的过程中,使用另一个哈希表来记录当前窗口内的字符及其出现次数,并与 p 中的字符计数进行比较。

  • 更新窗口:每次向右移动窗口时,添加新的字符到窗口的哈希表中,并从窗口中移除一个字符。

  • 判断异位词:如果在某个时刻,当前窗口内的字符计数与 p 中的字符计数相匹配,则说明找到了一个异位词,记录此时窗口的起始索引。

  • 继续滑动:继续滑动窗口直到遍历完整个字符串 s。

  • 返回结果:返回所有找到的异位词子串的起始索引列表。

  1. 复杂度:时间复杂度 O(n * m),空间复杂度 O(m)。
  2. 代码过程
  • 初始化一个哈希表 pCount 来存储 p 中字符的出现次数。

  • 初始化两个指针 left 和 right,分别指向当前考虑的窗口的起始和结束位置。

  • 使用一个哈希表 windowCount 来存储当前窗口内的字符计数。

  • 扩展窗口,直到窗口的大小等于 p 的长度。

  • 当窗口大小等于 p 的长度时,检查当前窗口是否是 p 的异位词:

    • 如果是,记录下 left 指针的位置,因为这是子串的起始索引。
    • 移动 right 指针来扩展窗口,并更新 windowCount。
  • 移动left 指针来收缩窗口,并更新 windowCount。

  • 重复步骤 5 和 6,直到 right 指针遍历完整个字符串 s。

  • 返回记录的所有起始索引。

  1. c++ demo
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>class Solution {
public:std::vector<int> findAnagrams(const std::string& s, const std::string& p) {std::vector<int> result;if (s.size() < p.size()) return result; // 如果s的长度小于p的长度,不可能有异位词// 用于存储p中字符的频率std::unordered_map<char, int> pFreq;for (char c : p) {pFreq[c]++;}// 用于存储当前窗口的字符频率std::unordered_map<char, int> windowFreq;int left = 0, right = 0; // 左右指针,定义当前窗口int validChars = 0; // 当前窗口中与p中字符匹配的字符数量// 窗口大小小于p时,继续扩展窗口while (right < s.size() && right - left < p.size()) {char c = s[right];if (pFreq.find(c) != pFreq.end()) {windowFreq[c]++;}right++;}// 当窗口大小等于p时,开始检查是否为异位词while (right - left == p.size()) {// 如果当前窗口是p的异位词,记录起始索引if (isAnagram(pFreq, windowFreq)) {result.push_back(left);}// 移动窗口char leftChar = s[left];if (pFreq.find(leftChar) != pFreq.end()) {if (windowFreq[leftChar] == pFreq[leftChar]) {validChars--;}windowFreq[leftChar]--;if (windowFreq[leftChar] < pFreq[leftChar]) {validChars++;}}left++;// 扩展窗口if (right < s.size()) {char rightChar = s[right];if (pFreq.find(rightChar) != pFreq.end()) {windowFreq[rightChar]++;if (windowFreq[rightChar] == pFreq[rightChar]) {validChars--;}}right++;}}return result;}private:// 辅助函数,用于比较两个字符计数映射是否相等bool isAnagram(const std::unordered_map<char, int>& pFreq,const std::unordered_map<char, int>& windowFreq) {for (const auto& kv : pFreq) {if (kv.second != windowFreq.at(kv.first)) {return false;}}return true;}
};int main() {Solution solution;std::string s = "cbaebabacd";std::string p = "abc";std::vector<int> anagramIndices = solution.findAnagrams(s, p);std::cout << "Start indices of anagrams of \"" << p << "\" in \"" << s << "\" are:" << std::endl;for (int index : anagramIndices) {std::cout << index << std::endl;}return 0;
}
  • 输出结果:

Start indices of anagrams of “abc” in “cbaebabacd” are:
0
6
在这里插入图片描述

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

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

相关文章

Python高阶学习记录

文章导读 阅读本文需要一定的python基础&#xff0c;部分知识点是对python入门篇学习记录和python并发编程学习记录的深入探究&#xff0c;本文记录的Python知识点包括函数式编程&#xff0c;装饰器&#xff0c;生成器&#xff0c;迭代器&#xff0c;正则表达式&#xff0c;内存…

eNSP——两台电脑通过一根网线直连通信

一、拓扑结构 二、电脑配置 ip和子网掩码&#xff0c;配置两台电脑处于同一网段 三、测试 四、应用 传文件等操作&#xff0c;可以在一台电脑上配置FTP服务器

Java零基础-顺序结构

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

高清矩阵是什么?

在数学中&#xff0c;矩阵是一个按照长方阵列排列的复数或实数集合&#xff0c;最早来自于方程组的系数及常数所构成的方阵。如图为m行n列的矩阵&#xff1a; 由此延伸可以想到矩阵图片是把一个三维空间分切成多个行和列的区域进行图像捕获&#xff0c;将捕获图像再进行拼合成为…

关于苹果发布IOS18系统,以及Siri升级贾维斯

随着科技的不断进步&#xff0c;手机操作系统也在持续升级&#xff0c;为用户提供更加智能化、便捷化的体验。近期&#xff0c;苹果公司即将推出的iOS 18系统引起了广泛关注。作为iPhone历史上的重大更新&#xff0c;iOS 18系统带来了众多新功能&#xff0c;将进一步提升iPhone…

2024-6-2 石群电路-21

2024-6-2&#xff0c;星期日&#xff0c;天气&#xff1a;阴&#xff0c;心情&#xff1a;晴。今天没什么特别的事情发生&#xff0c;心情还是一如既往的好&#xff0c;明天就周一啦&#xff0c;虽然我暂时不用上班&#xff0c;但是希望大家新的一周元气满满~ 今日观看了石群老…

STL中vector动态二维数组理解(杨辉三角)

题目链接&#xff1a;118.杨辉三角 题目描述&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 题目指要&#xff1a; 本题的主要目的是理解vector<vector<int&…

18 跨团队 没有汇报线的人和事就是推不动?

在“05 | 大项目&#xff1a;把握关键点&#xff0c;谋定而后动”和“11 | 勤沟通&#xff1a;在信任的基础上&#xff0c;让沟通简单”两讲中&#xff0c;我提过“跨团队”这件事&#xff0c;很多同学带团队之后&#xff0c;无法回避的一个问题就是“跨团队协作”&#xff0c;…

【Linux】System V 消息队列(不重要)

一、消息队列的原理 一个进程给另一个进程发送类型数据块的方式每一个数据快都被认为是有一个类型的&#xff0c;接收者进程接收的数据快可以有不同的类型值 二、消息队列的接口 和共享内存的接口很像&#xff1a; 消息队列的创建 创建消息队列我们需要用msgget函数&#x…

logging二次封装

import logging import os import time from logging.handlers import RotatingFileHandlerclass Logger():logs_dir os.path.dirname(os.path.dirname(os.path.abspath(__file__))) \\report\\logsdef __init__(self, name):self.logger logging.getLogger(name)#设置级别…

JavaScript函数进阶学习

文章目录 JavaScript函数进阶函数提升作用流程 函数参数动态参数剩余参数展开运算符 箭头函数基本语法箭头函数参数箭头函数的this 遍历数组的forEach方法语法 JavaScript函数进阶 函数提升 函数有时可以先调用再声明。 作用流程 函数提升的作用流程与变量提升类似&#xf…

移动端框架:加速移动应用开发与提升跨平台兼容性

在当今快速发展的移动应用领域&#xff0c;开发者们面临着如何快速构建、维护并发布跨平台应用的挑战。为了应对这一挑战&#xff0c;移动端框架应运而生&#xff0c;它们不仅加速了移动应用的开发流程&#xff0c;还提升了应用的跨平台兼容性&#xff0c;并确保了应用性能与原…

C++的算法:动态规划算法

动态规划(Dynamic Programming,简称DP)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式来求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。 动态规划的基本步骤: 1. 描述问题的最优解的结构:确定问题的…

2024/6/2 英语每日一段

However, they denied Hirst had been deliberately misleading, arguing that it was his “usual practice” to date physical works in a conceptual art project with the date of the project’s conception, which in the case of The Currency was 2016. Hirst and Sci…

Python | 自动探索性数据分析(EDA)库SweetViz

SweetViz是一个开放源代码Python库&#xff0c;主要用于生成精美的高密度可视化文件&#xff0c;启动探索性数据分析&#xff08;EDA&#xff09;&#xff0c;输出为完全独立的HTML应用程序。 探索性数据分析&#xff08;EDA&#xff09;是分析和总结数据集主要特征的过程&…

uni-app(优医咨询)项目实战 - 第7天

学习目标&#xff1a; 能够基于 WebSocket 完成问诊全流程 能够使用 uniCloud 云存储上传文件 能够完成查看电子处方的功能 能够完成医生评价的功能 一、问诊室 以对话聊天的方式向医生介绍病情并获取诊断方案&#xff0c;聊天的内容支持文字和图片两种形式。 首先新建一…

AOP案例

黑马程序员JavaWeb开发教程 文章目录 一、案例1.1 案例1.2 步骤1.2.1 准备1.2.2 编码 一、案例 1.1 案例 将之前案例中增、删、改相关节后的操作日志记录到数据库表中。 操作日志&#xff1a;日志信息包含&#xff1a;操作人、操作时间、执行方法的全类名、执行方法名、方法…

网关(Gateway)- 内置过滤器工厂

官方文档:Spring Cloud Gateway 内置过滤器工厂 AddRequestHeaderGatewayFilterFactory 为请求添加Header Header的名称及值 配置说明 server:port: 8088 spring:application:name: api-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8847username: nacospassword: …

Java中的垃圾回收机制详解

一、技术难点 Java中的垃圾回收机制&#xff08;Garbage Collection, GC&#xff09;是Java语言的一个核心特性&#xff0c;它负责自动管理堆内存中的对象&#xff0c;自动回收不再使用的对象占用的内存空间&#xff0c;从而避免了C/C等语言中常见的内存泄漏和野指针问题。然而…

52.WEB渗透测试-信息收集-CDN识别绕过(5)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;51.WEB渗透测试-信息收集-CDN识别绕过&#xff08;4&#xff09; 端口扫描其他内容参考&…