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

问题描述

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

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

解题思路1

注意:该解题思路是错误的,正确的是解题思路2

这道题目首先想到的肯定是通过多层循环来遍历:

  1. 提取子串:遍历s字符串,提取长度和p相同的子串
  2. 字符匹配:创建p的副本,对于提取的子串中的每个字符,尝试在p的副本中找到并移除。如果某个字符在p的副本中不存在,说明该子串不是异位词。
  3. 结果记录:如果所有字符都成功匹配并且p的副本被完全清空,将当前起始位置添加到结果中。

代码实现

class Solution {
public:vector<int> findAnagrams(string s, string p) {vector<int> results;int p_len = p.length();int s_len = s.length();if (s_len < p_len)return results;// 遍历s中的每个可能的起始位置for (int start = 0; start <= s_len - p_len; ++start) {string substr = s.substr(start, p_len); // 获取当前考虑的子串string temp_p = p; // 创建p的一个副本以供修改// 遍历当前子串中的每个字符bool matched = true;for (char c : substr) {size_t pos = temp_p.find(c); // 在p的副本中查找当前字符if (pos != string::npos) {temp_p.erase(pos, 1); // 如果找到,从p的副本中移除该字符} else {matched = false; // 如果未找到,标记不匹配并跳出循环break;}}if (matched && temp_p.empty()) { // 检查是否所有p中的字符都被匹配results.push_back(start);}}return results;}
};

当提交答案时提示“超出时间限制”。

回头来看这里的问题:

这种方法的时间复杂度较高,因为它涉及到在每个可能的子串中对每个字符进行查找和删除操作,每次删除操作可能涉及到字符串的重构,其时间复杂度最坏情况下接近O(n * m^2),其中n是字符串s的长度,m是字符串p的长度。这可能在输入字符串较长时导致性能问题。

解题思路2

通过对上面思路的反思,我认为这道题吗不能用多层循环嵌套处理,所以还是从题目本身出发。

我发现最核心的就是如何判断子串是否为异位词,上面通过循环遍历比较来判断的效率太低,就不能用循环遍历比较了。

核心思路:因为异位词不关心字符的顺序,只关心字符能不能被匹配上,那就是要判断字符在子串中出现的次数和出现在p的次数是否相同,如果相同就说明子串属于异位词。

解决这一问题的核心思路是利用滑动窗口技术和字符频率统计:

  1. 字符频率统计:首先,我们需要一个方式来快速判断两个字符串是否为异位词。最直接的方法是使用一个固定大小为26的数组(假设输入字符串只包含小写字母)来统计每个字母在字符串中出现的频率。

  2. 滑动窗口:这是一种常用于处理数组和字符串的技术。基本思想是维护一个窗口,这个窗口可以增大也可以缩小,随着窗口的滑动,我们可以在O(1)的时间内更新窗口内的信息。在这个问题中,我们将窗口的大小固定为字符串p的长度,并在s中从左到右滑动这个窗口。

代码实现

class Solution {
public:vector<int> findAnagrams(string s, string p) {vector<int> result;if (s.size() < p.size())return result;// 创建字符频率表vector<int> p_count(26, 0), s_count(26, 0);for (char c : p) {p_count[c - 'a']++;}int left = 0, right = 0, p_length = p.size();while (right < s.size()) {// 增加右侧字符频率s_count[s[right] - 'a']++;// 当窗口大小等于p的长度时,比较两个频率表if (right - left + 1 == p_length) {if (s_count == p_count) {result.push_back(left);}// 移动窗口,减少左侧字符频率s_count[s[left] - 'a']--;left++;}right++;}return result;}
};

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

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

相关文章

Microsoft VBA Excel 操控 Access资料表和查询代码进行搬运操作

问题场景 Run_NoSource_AddressSource_FileDestination_AddressDestination_FileCopy_IndicatorRun_Start_Time1C:\Users\EP\path\to\FileSSS-1.MDBC:\Users\EP\path\to\FileSSC-1.MDBY2C:\Users\EP\path\to\FileSSS-2.MDBC:\Users\EP\path\to\FileSSC-2.MDBY3C:\Users\EP\pat…

NC参照 根据名称转换为主键值,如部门、人员等参照根据部门名称、人员名称获取对应的主键值

NC参照 根据名称转换为主键值&#xff0c;如部门、人员等参照根据部门名称、人员名称获取对应的主键值 private BillCardPanel getEditBillCardPanel() {return getEditor().getBillCardPanel(); }private BillData getEditorBillData() {return this.getEditor().getBillCard…

静态库和动态库

1、编译过程 1.预处理&#xff1a;解释并展开源程序当中的所有的预处理指令&#xff0c;此时生成 *.i 文件。 2.编译&#xff1a;词法和语法的分析&#xff0c;生成对应硬件平台的汇编语言文件&#xff0c;此时生成 *.s 文件。 3.汇编&#xff1a;将汇编语言文件翻译为对应处理…

便携式烟气监测仪的应用主要有哪些?

烟气分析仪是一种用于检测和分析烟气中各种成分和污染物含量的仪器&#xff0c;通过采集和处理烟气样品&#xff0c;对其中的各种成分进行定量分析。那么&#xff0c;便携式烟气监测仪的应用主要有哪些&#xff1f;为方便大家了解&#xff0c;下面就让小编来为大家简单介绍一下…

2-2到2-4

计算出所有人的平均年龄&#xff1a; val lines sc.textFile("/root/data/scala/people/page.txt") val count lines.count() val total lines.map(line > line.split(" ")(1)).map(t>t.trim.toInt).collect().reduce((a,b)>ab) val avgAge …

如何防止SQL注入

为了防止SQL注入攻击&#xff0c;可以采取以下一系列的安全措施&#xff0c;这些措施结合了多篇参考文章中的关键信息和方法&#xff1a; 使用参数化查询或预编译语句&#xff1a; 这是防止SQL注入的最常见且最有效的方法之一。通过将用户输入的数据作为参数传递给SQL查询语句…

[Python]根据文件路径获取文件所在目录、文件名和后缀名

一、简介 本文介绍了在python中如何根据文件的路径名字&#xff08;字符串&#xff09;获取文件所在目录名、文件名&#xff08;带后缀&#xff09;、文件名&#xff08;无后缀&#xff09;和文件后缀名。 二、代码 假设文件路径为/home/user/temp.txt&#xff0c;使用以下代…

压缩pdf文件大小的方法,如何压缩pdf格式的大小

pdf太大怎么压缩&#xff1f;当你需要通过电子邮件发送一个PDF文件&#xff0c;却发现文件太大无法成功发出时&#xff0c;这些情况下&#xff0c;我们都需要找到一种方法来压缩PDF文件&#xff0c;以便更便捷地进行分享和传输。PDF文件的大小通常与其中包含的图片、图形和文本…

入门JavaWeb之 Response 下载文件

web 服务器接收到客户端的 http 请求 针对这个请求&#xff0c;分别创建一个代表请求的 HttpServletRequest 对象&#xff0c;代表响应的 HttpServletResponse 对象 获取客户端请求过来的参数&#xff1a;HttpServletRequest 给客户端响应一些信息&#xff1a;HttpServletRe…

数据库索引失效的11种情况

MySQL中 提高性能 的一个最有效的方式是对数据表 设计合理的索引。索引提供了高效访问数据的方法&#xff0c;并且加快查询的速度&#xff0c;因此索引对查询的速度有着至关重要的影响。使用索引可以 快速地定位 表中的某条记录&#xff0c;从而提高数据库査询的速度&#xff0…

js获取选中区域(window.getSelection的基本使用)

返回一个 Selection 对象&#xff0c;表示用户选择的文本范围或光标的当前位置。 const selection window.getSelection() 1.toString() //光标选中的文本 const selectedText selection.toString() 2.getRangeAt() //返回一个包含当前选区内容的区域对象。 selection…

数据与文字的表示方法

目录 1. 数据格式 1. 文本文件格式 2. 二进制文件格式 3. 数据库格式 4. 压缩格式 2. 数字机器码表示 整数表示 浮点数表示 3. 字符与数组的表示方法 1. ASCII&#xff08;美国信息交换标准代码&#xff09; 2. 扩展ASCII 3. Unicode 4. UTF-8&#xff08;8 位 Uni…

面试相关-接口测试常问的问题

1.为什么要做接口测试 (1)现在大多系统都是前后端分离的项目,前端和后端的进度可能不一样,那为了尽早的进入测试,前端界面没有开发完成的情况下,只要后端的接口开发完了,就可以提前做接口测试了; (2)基于安全考虑,只依赖前端进行限制,已经完全不满足系统的安全性…

Power Pivot——常用DAX 函数

常用DAX 函数 以下这些函数是 DAX 中最常用的一部分&#xff0c;通过熟练掌握这些函数&#xff0c;你可以有效地进行数据分析和建模。 聚合函数 (Aggregation Functions) SUM() 用途&#xff1a;对指定列中的所有数值求和。 语法&#xff1a;SUM() 示例&#xff1a;SUM(Sale…

重生之我要学后端01--后端语言选择和对应框架选择

编程语言 后端开发通常需要掌握至少一种编程语言。以下几种语言在后端开发中非常流行&#xff1a; Java&#xff1a;广泛用于企业级应用程序。Python&#xff1a;因其易学性和强大的库支持&#xff08;如Django和Flask&#xff09;而受欢迎。Node.js&#xff08;JavaScript&a…

电商卖家怎么快速采集复制1688全店宝贝到自己店铺?淘/猫/拼/抖都适用!

1688上面的货源品类丰富&#xff0c;很多卖家都是在这里找厂家&#xff0c;当我们找好厂家后&#xff0c;怎么将厂家店铺里所有宝贝都复制到自己店铺呢&#xff1f; 虽然1688平台本身支持铺货到其他平台&#xff0c;但一个个铺货太耗费时间了。 阿里巴巴中国站获得1688商品详…

【AI大模型RAG】深入探索检索增强生成(RAG)技术

目录 1. 引言2. RAG技术概述2.1 RAG技术的定义2.2 RAG技术的工作原理2.3 RAG技术的优势2.4 RAG技术的应用场景 3. RAG的工作流程3.1 输入处理3.2 索引建立3.3 信息检索3.4 文档生成3.5 融合与优化 4. RAG范式的演变4.1 初级 RAG 模型4.2 高级 RAG 模型4.3 模块化 RAG 模型优化技…

会计报表分析

目录 一. 会计报表的种类 \quad 一. 会计报表的种类 \quad 反应财务状况的是资产负债表 反应经营成果的是利润表 有时间点的就是静态表 动态表就是有一个区间的, 比如一年, 一个季度等

探索这些有趣的API,让你的应用与众不同

在这个由数据驱动的时代&#xff0c;我们每天都在与各种应用程序和服务互动&#xff0c;却很少意识到它们背后的技术奇迹。API&#xff0c;作为这些互动的幕后英雄&#xff0c;不仅简化了开发过程&#xff0c;还扩展了技术的边界。有趣的API&#xff0c;特别是那些能够激发创新…

QT 如何储存多种数据类型(QVariant )

QVariant 是 Qt 框架中用于存储各种数据类型的类。它提供了一个强大的类型系统&#xff0c;允许你在运行时存储和检索多种类型的数据&#xff0c;而不需要在编译时确定类型。QVariant 的主要优点在于它的灵活性和通用性&#xff0c;这使得它在 Qt 的很多组件和机制中都被广泛使…