力扣hot100:438.找到字符串中所有字母异位词

2024-03-05 10:04

本文主要是介绍力扣hot100:438.找到字符串中所有字母异位词,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

26个字符,我复制怎么了?26个字符我比较个数怎么了? 顶多时间复杂度*26

本题用固定窗口大小的滑动窗口+每次比较包含26个元素的数组次数,最容易写。

动态窗口大小+哈希表存数值(双指针差值)难想难写。

一、动态滑动窗口+哈希表(双指针)

        这个问题,刚开始想的是,维护一个滑动窗口,左指针left,右指针right,左指针往右走从集合中拿走这个字符,右指针往右走在集合中加入这个字符,但是由于p可能有多个重复字符,这使得我们不得不记录字符的个数了。那,我们记录个数的话,怎么记录呢?可以用哈希表存储该字符的个数,如果集合中加入一个字符,字符个数就减1,直至哈希表中没有元素则说明匹配成功,但是匹配了一次之后呢? 重新复制一次不得了,最多26个字符!

        不过这里需要注意的是,当匹配成功后,左右指针都只能往后移动一次,只有当右指针遇到的字符不在目标字符串中时,才复制一次,完全重开。

        这里的字符个数完全确定,最好使用vector<int>,查找更快。

class Solution {
public:vector<int> findAnagrams(string s, string p) {int left=0;int right=0;unordered_map<char,int> source;for(auto &i:p) source[i]+=1;//可以复制,就26个字母,我复制怎么了?vector<int> ans;unordered_map<char,int> hmap(source);while(right<s.size()){if(hmap.find(s[right])!=hmap.end()){//在里面hmap[s[right]]-=1;if(hmap[s[right]]==0) hmap.erase(s[right]);if(hmap.size()==0){ans.emplace_back(left);hmap[s[left++]]=1;}++right;}else{if(source.find(s[right])!=source.end()){//它在源头里面 可能有点用的hmap[s[left++]]+=1;}else {hmap=source;//注意这里! 这里得还原了left=++right;}}}return ans;}
};

vector实现:

class Solution {
public:vector<int> findAnagrams(string &s, string &p) {if(s.size()<p.size()) return {};vector<int> cnt_s(26);vector<int> cnt_p(26);vector<int> ans;vector<int> zero(26);for(char &i:p) ++cnt_p[i-'a'];cnt_s=cnt_p;int left=0,right=0;while(right<s.size()){if(cnt_s[s[right]-'a']>0){--cnt_s[s[right]-'a'];++right;}else{if(cnt_p[s[right]-'a']>0){cnt_s[s[left]-'a']++;++left;}else{cnt_s=cnt_p;left=right=right+1;}}if(cnt_s==zero) ans.push_back(left);}return ans;}
};

二、固定滑动窗口

这里实际上就是上述方法用vector实现的。由于是26个字符,直接比较就行了。

class Solution {
public:vector<int> findAnagrams(string &s, string &p) {if(s.size()<p.size()) return {};vector<int> source(26);vector<int> hmap(26);vector<int> ans;for(int i=0;i<p.size();++i){hmap[s[i]-'a']+=1;source[p[i]-'a']+=1;}int left=0,right=p.size();while(right<s.size()){if(hmap == source) ans.emplace_back(left);hmap[s[left++]-'a']-=1;hmap[s[right++]-'a']+=1;}if(hmap == source) ans.emplace_back(left);return ans;}
};

这篇关于力扣hot100:438.找到字符串中所有字母异位词的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/776149

相关文章

Java中字符串转时间与时间转字符串的操作详解

《Java中字符串转时间与时间转字符串的操作详解》Java的java.time包提供了强大的日期和时间处理功能,通过DateTimeFormatter可以轻松地在日期时间对象和字符串之间进行转换,下面... 目录一、字符串转时间(一)使用预定义格式(二)自定义格式二、时间转字符串(一)使用预定义格式(二)自

Python实现特殊字符判断并去掉非字母和数字的特殊字符

《Python实现特殊字符判断并去掉非字母和数字的特殊字符》在Python中,可以通过多种方法来判断字符串中是否包含非字母、数字的特殊字符,并将这些特殊字符去掉,本文为大家整理了一些常用的,希望对大家... 目录1. 使用正则表达式判断字符串中是否包含特殊字符去掉字符串中的特殊字符2. 使用 str.isa

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

MySQL中动态生成SQL语句去掉所有字段的空格的操作方法

《MySQL中动态生成SQL语句去掉所有字段的空格的操作方法》在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况,本文将详细介绍如何在MySQL中动态生成SQL语句来去掉所有字段的空... 目录在mysql中动态生成SQL语句去掉所有字段的空格准备工作原理分析动态生成SQL语句在MySQL

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘