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

        leetcode原题链接找到字符串中所有字母异位词

        上一篇HOT8-无重复字符的最长子串

        下一篇HOT10-和为K的子数组

题目描述

       给定两个字符串 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的长度为p_n,在主串s中维护一个长度为p_n的滑动窗口,窗口区间为[left, right],我们将p[left, right]和s分别映射到两个长度为26的数字字符串数组p1和p2中,该数组对应的每一位表示对应字母出现在字符串中出现的次数,p[left, right]和s互为异位词的条件是p1 = p2,通过滑动窗口动态改变p[left, right]中的left和right的值。

C++代码

#include <string>
class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int s_n = s.size();
        int p_n = p.size();
        if (s_n < p_n) { //这里不能漏,否则下面访问的时候数组会越界
            return {};
        }
        std::string s1(26, '0');//保存s当前滑动窗口的异位词各个字母出现的次数
        std::string p1(26, '0');//保存目标p的各个字母出现的次数
        std::vector<int> result;
        for (int i = 0; i < p_n; i++) {
            // 先生成p的异位词
            char ch_p = p[i];
            p1[ch_p - 'a']++;
            // 判断当前s.substr(0, len)是否为异位词(生成一个长度为目标异位词长度的子串)
            char ch_s = s[i];
            s1[ch_s - 'a']++;
        }
        if (s1 == p1) { //判断当前的窗口是否匹配
            result.emplace_back(0);
        }
        // start表示新滑动窗口的起点
        for (int start = 1; start <= s_n - p_n; start++) {
            char old_start_ch = s[start - 1];//旧滑动窗口起点
            char new_end_ch = s[start + p_n - 1]; //新滑动窗口终点
            s1[old_start_ch - 'a']--;//旧滑动窗口起点对应字母对应的次数少1
            s1[new_end_ch - 'a']++;//新滑懂窗口终点对应的字母出现的次数加1
            if (s1 == p1) {
                result.emplace_back(start);
            }
        }
        return result;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值