1、题目描述
给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。
说明:
- 字母异位词指字母相同,但排列不同的字符串。
- 不考虑答案输出的顺序。
2、示例
输入:
s: "cbaebabacd" p: "abc"
输出:
[0, 6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的字母异位词。
3、题解
基本思想:滑动窗口+哈希表HashMap,用哈希表表示窗口大小为p.size的s字符串中字符对应个数映射,如果Map1==Map2说明该窗口满足条件res.push_back(i)。
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
class Solution0 {
public:
vector<int> findAnagrams(string s, string p) {
if(s.size()==0||s.size()<p.size()) return {};
map<char,int> HashMap1;
map<char,int> HashMap2;
for(int i=0;i<p.size();i++){
HashMap1[p[i]]++;
HashMap2[s[i]]++;
}
vector<int> res;
for(int i=0;i<s.size();i++){
if(HashMap1==HashMap2){
res.push_back(i);
}
HashMap2[s[i]]--;
if(HashMap2[s[i]]==0) {
HashMap2.erase(s[i]);
}
if(i+p.size()<s.size()){
HashMap2[s[i+p.size()]]++;
}
}
return res;
}
};
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
//基本思想:滑动窗口+哈希表HashMap
//用哈希表表示窗口大小为p.size的s字符串,如果Map1==Map2说明该窗口满足条件,res.push_back(i)
if(s.size()==0||s.size()<p.size()) return {};
vector<int> Map1(26,0);
vector<int> Map2(26,0);
vector<int> res;
//初始化Map1映射p中字符对应个数
for(auto ch:p)
Map1[ch-'a']++;
//初始化Map2映射窗口为p.size的s中字符对应个数
for(int i=0;i<p.size();i++)
Map2[s[i]-'a']++;
//滑动窗口起始位置从0到s.size()-p.size(),如果Map1==Map2说明该窗口满足条件,res.push_back(i)
for(int i=0;i<=s.size()-p.size();i++)
{
if(Map1==Map2)
res.push_back(i);
if(i+p.size()==s.size()) break;
//更新窗口内字符映射,即下一个窗口的字符对应个数
Map2[s[i]-'a']--;
Map2[s[i+p.size()]-'a']++;
}
return res;
}
};
int main()
{
Solution solute;
string s="aaaaaaaaaa";
string p="aaaaaaaaaaaaa";
vector<int> res=solute.findAnagrams(s,p);
for_each(res.begin(),res.end(),[](int v){cout<<v<<endl;});
return 0;
}
博客围绕LeetCode题目展开,给定字符串s和非空字符串p,需找出s中p的字母异位词子串起始索引。介绍了示例,输入s: \cbaebabacd\、p: \abc\,输出为[0, 6]。题解采用滑动窗口和哈希表HashMap,通过比较字符个数映射判断窗口是否满足条件。
465

被折叠的 条评论
为什么被折叠?



