leetcode-438:找到字符串中所有字母异位词

简介: leetcode-438:找到字符串中所有字母异位词

题目

题目连接

给定两个字符串 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" 的异位词。

解题

方法一:定长滑动窗口(暴力)

一个和p一样长度的滑动窗口,然后用vector作为哈希,记录每个元素出现的次数,然后比较vector相等就行了,比较暴力的解法。

class Solution {
public:
    bool isValid(vector<int>& a,vector<int>& b){
        for(int i=0;i<26;i++){
            if(a[i]!=b[i]) return false;
        }
        return true;
    }
    vector<int> findAnagrams(string s, string p) {
        int n=p.size();
        vector<int> hash(26,0),cur(26,0);
        for(char c:p){
            hash[c-'a']++;
        }
        vector<int> res;
        for(int i=0;i<s.size();i++){
            if(i>=n){
                cur[s[i-n]-'a']--;
            }
            cur[s[i]-'a']++;
            if(i>=n-1&&isValid(hash,cur)){
                res.push_back(i-n+1);
            }
        }
        return res;
    }
};

方法二:变长滑动窗口

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int n=p.size();
        vector<int> hash(26,0),cur(26,0);
        for(char c:p){
            hash[c-'a']++;
        }
        vector<int> res;
        int left=0;
        for(int right=0;right<s.size();right++){
            int idx=s[right]-'a';
            cur[idx]++;
            while(cur[idx]>hash[idx]){//如果新加了字符后,使得该字符数量多于p的,那么滑动窗口左边界开始向右滑动
                cur[s[left]-'a']--;
                left++;
            }
            if(right-left+1>=n){//滑动窗口的大小为n就说明符合异位词的条件
                res.push_back(right-n+1);
            }
        }
        return res;
    }
};
相关文章
|
3月前
|
存储 算法
LeetCode第49题字母异位词分组
LeetCode第49题"字母异位词分组"的解题方法,通过将每个字符串的字符排序后作为键存储在HashMap中,有效地将所有字母异位词分组。
LeetCode第49题字母异位词分组
|
24天前
|
JavaScript
力扣3333.找到初始输入字符串Ⅱ
【10月更文挑战第9天】力扣3333.找到初始输入字符串Ⅱ
31 1
|
1月前
|
C++
Leetcode第43题(字符串相乘)
本篇介绍了一种用C++实现的字符串表示的非负整数相乘的方法,通过逆向编号字符串,将乘法运算转化为二维数组的累加过程,最后处理进位并转换为字符串结果,解决了两个大数相乘的问题。
24 9
|
1月前
|
存储
Leetcode第49题(字母异位词分组)
LeetCode第49题要求将字符串数组中的字母异位词分组,可以通过将每个字符串排序后作为键存入哈希表,最后将哈希表中的值添加到结果列表中来实现。
15 1
|
1月前
|
算法
Leetcode第十七题(电话号码的字母组合)
这篇文章介绍了如何使用深度优先搜索(DFS)算法来解决LeetCode第17题——电话号码的字母组合问题,通过递归方法生成所有可能的字母组合。
16 0
Leetcode第十七题(电话号码的字母组合)
|
1月前
|
索引
【LeetCode 11】242.有效的字母异位词
【LeetCode 11】242.有效的字母异位词
15 0
【LeetCode 11】242.有效的字母异位词
|
1月前
|
算法
【LeetCode 52】17.电话号码的字母组合
【LeetCode 52】17.电话号码的字母组合
31 0
|
1月前
|
算法 C++
Leetcode第八题(字符串转换整数(atoi))
这篇文章介绍了LeetCode上第8题“字符串转换整数(atoi)”的解题思路和C++的实现方法,包括处理前导空格、正负号、连续数字字符以及整数溢出的情况。
17 0
|
1月前
【LeetCode 22】459.重复的子字符串
【LeetCode 22】459.重复的子字符串
28 0
|
1月前
【LeetCode 20】151.反转字符串里的单词
【LeetCode 20】151.反转字符串里的单词
19 0