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;
    }
};
相关文章
|
2月前
|
存储 算法
LeetCode第49题字母异位词分组
LeetCode第49题"字母异位词分组"的解题方法,通过将每个字符串的字符排序后作为键存储在HashMap中,有效地将所有字母异位词分组。
LeetCode第49题字母异位词分组
|
2月前
|
存储 算法
LeetCode第43题字符串相乘
LeetCode第43题"字符串相乘"的解题方法,通过使用数组存储乘积并处理进位,避免了字符串转换数字的复杂性,提高了算法效率。
LeetCode第43题字符串相乘
|
2月前
|
算法 Java
LeetCode第28题找出字符串中第一个匹配项的下标
这篇文章介绍了LeetCode第28题"找出字符串中第一个匹配项的下标"的两种解法:暴力解法和KMP算法,并解释了KMP算法通过构建前缀表来提高字符串搜索的效率。
LeetCode第28题找出字符串中第一个匹配项的下标
|
2月前
|
算法
LeetCode第17题电话号码的字母组合
该文章介绍了 LeetCode 第 17 题电话号码的字母组合的解法,通过分析得出可使用递归和回溯的思想解决,避免循环穷举的高循环次数,并给出了具体的编码实现,同时总结了该题较难理解,需要了解递归的本质,当嵌套循环层次多时可考虑递归。
LeetCode第17题电话号码的字母组合
|
2月前
|
算法
LeetCode第8题字符串转换整数 (atoi)
该文章介绍了 LeetCode 第 8 题字符串转换整数 (atoi)的解法,需要对字符串进行格式解析与校验,去除前导空格和处理正负号,通过从高位到低位的计算方式将字符串转换为整数,并处理越界情况。同时总结了这几道题都需要对数字的表示有理解。
LeetCode第8题字符串转换整数 (atoi)
|
4月前
|
算法
力扣每日一题 6/23 字符串/模拟
力扣每日一题 6/23 字符串/模拟
31 1
|
4月前
|
索引
力扣每日一题 6/27 字符串 贪心
力扣每日一题 6/27 字符串 贪心
27 0
|
4月前
|
Python
力扣随机一题 模拟+字符串
力扣随机一题 模拟+字符串
24 0
|
4月前
力扣每日一题 6/22 字符串/贪心
力扣每日一题 6/22 字符串/贪心
23 0
|
4月前
力扣每日一题 6/18 字符串/模拟
力扣每日一题 6/18 字符串/模拟
21 0