给定两个字符串 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 * 104s和p仅包含小写字母
思路1
1、创建返回参数vector<int> ans。检查参数的合法性,s或者p为空、p的长度大于s时,返回空vector。
2、给p排序,分别求出s的长度s_len,p的长度p_len。
3、创建两个指针left=0,right=p_len-1。
4、copy出left和right指向的字符串,然后对其进行排序。
5、判断排序两个字符串是否相等,相等则将left的下标加入ans,不相等则跳过。
6、left和right都向前走一格,直到right走到数组的最后一个位置。
cpp
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> ans;
if(s.empty()||p.empty()||p.size()>s.size()) return ans;
if (s == p) {
ans.push_back(0);
return ans;
}
sort(p.begin(),p.end());
int s_len=s.size();
int p_len=p.size();
int left=0,right=p_len-1;
while(right<s_len){
string _temp=s.substr(left,p_len);
sort(_temp.begin(),_temp.end());
if(_temp==p) ans.push_back(left);
left++;
right++;
}
return ans;
}
};
结论:该思路正确,但是时间复杂度高,无法通过全部用例
思路2
1、不要用sort函数排序后再比较两个字符串是否相等。
2、用一个vector<int> word(26)类型的数组代表26个字母,0代表a,1代表b等以此类推。每出现该字母时,该字母的下标+1。比如出现一个a,那么word0+1,出现一个b,那么word1=1以此类推。
3、直接用vector<int>==vector<int>的方法判断两个数组是否相等。
步骤
1、创建返回参数vector<int> ans。检查参数的合法性,s或者p为空、p的长度大于s时,返回空vector,和p完全相等时,直接把0丢到ans中直接返回。
2、创建一个vector<int>,word_s,然后记录字符串p的字符个数。
3、计算s和p的长度,s_len、p_len。
4、创建两个指针left和right,left指向0,right指向p_len-1,开始循环。
5、创建两个vector<int> 数组word_s、word_p,用于计算string的字符个数。
6、先循环计算s字符串和p字符创,left到righr上的字符串个数。
7、while循环,先判断两个word_s、word_p是否相等,相等把left加入ans数组中,不相等直接跳过。
8、在word_s删掉left指向的字符,left++,right++,把sleft字符串加入word_s数组中。
9、继续判断两个word_s、word_p是否相等,直到循环结束。
cpp
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int>ans;
int n_s=s.size();
int n_p=p.size();
if(n_s==0||n_p==0||n_p>n_s) return ans;
vector<int> vec_s(26,0);
vector<int> vec_p(26,0);
for(int i=0;i<n_p;i++){
vec_p[p[i]-'a']++;
}
int left=0;
int right=n_p-1;
for(int i=0;i<right;i++){
vec_s[s[i]-'a']++;
}
for(int i=right;i<n_s;i++){
vec_s[s[i]-'a']++;
if(vec_p==vec_s) ans.push_back(left);
vec_s[s[left]-'a']--;
left++;
}
return ans;
}
};
推荐一个零声教育学习教程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,点击立即学习:链接