9 找到字符串中所有字母异位词

给定两个字符串 sp,找到 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
  • sp 仅包含小写字母
思路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等技术内容,点击立即学习:链接

相关推荐
Sw1zzle2 小时前
算法入门(六):贪心算法 - 基础入门(Leetcode 121/455/860/376/738)
算法·leetcode·贪心算法
青山木2 小时前
Hot 100 --- 岛屿数量
java·数据结构·算法·leetcode·深度优先·广度优先
不会就选b2 小时前
算法日常・每日刷题--<归并排序>1
数据结构·算法
危桥带雨2 小时前
排序算法(快排、归并、计数、基数排序)
数据结构·算法·排序算法
啦啦啦啦啦zzzz2 小时前
算法:回溯算法
c++·算法·leetcode
IT探索3 小时前
Linux 查找文件指令总结
linux·算法
Lzg_na3 小时前
订阅发布模块事例
c++
郝学胜-神的一滴3 小时前
[简化版 GAMES 104] 现代游戏引擎 02:拆解现代游戏引擎5+1层级架构,吃透引擎底层核心逻辑
c++·unity·架构·游戏引擎·图形渲染·unreal engine·系统设计