力扣438. 找到字符串中所有字母异位词(滑动窗口)

Problem: 438. 找到字符串中所有字母异位词

题目描述

在这里插入图片描述在这里插入图片描述

思路

本题目在使用滑动窗口技巧的基础上先要对原字符串做一些处理,具体的:

1.利用数组设置一个位图将字符串P存入数组(下标索引为小写英文字母的顺序,对应存储的值为其个数:vector needs(26,0);needs[p[i] - ‘a’]++;);
2.利用同样的方式将字符串S中的小于等于字符串P中的子串先存入另一个位图mached;
3.从字符串S中大于字符串P的部分开始,每次利用双指针循环先添加一个字符进mached,再在原来的基础上减去一个末尾一个字符以达到动态维护滑动窗口的操作,在动态维护滑动窗口的过程中需要同时比较两个位图needs和matched是否一致,若一致则说明当前位置为一个字母异位词的起始位置,并将其记录到一个结果集中

解题方法

1.编写比较两个数组给定范围所存储内容是否一致的函数same(vector& need, vector& matched);
2.获取字符串S和P的长度,sLen、pLen;
3.创建位图needs,将字符串P中的字符和其对应的个数存入vector needs(26,0);needs[p[i] - ‘a’]++;);
4.定义两个指针int starP = 0;int endP = 0;,并且利用指针endP将字符串S中长度等于字符串P长度的子串存入另一个位图matched(vector matched(26,0);while (endP < pLen) {matched[s[endP] - ‘a’]++;endP++;});
5.定义结果集vector result;,并判断一次此时位图needs和matched是否完全一致,若一致则表明初始时S中的一个子串就为一个字母异位词
6.在上述操作中已经是抽象地完成了滑动窗口的创建,再按照思路中的3进行滑动窗口的动态维护;

复杂度

时间复杂度:

O ( n ) O(n) O(n),其中 n n n为字符串S的长度(假设 s L e n > > p L e n sLen>>pLen sLen>>pLen);

空间复杂度:

O ( 1 ) O(1) O(1)

Code

class Solution {
public:
    /**
     * Sliding window
     *
     * @param s The string given to be matched
     * @param p Substring
     * @return vector<int>
     */
    vector<int> findAnagrams(string s, string p) {
        int sLen = s.length();
        int pLen = p.length();
        if (pLen > sLen) {
            return {};
        }
        vector<int> needs(26,0);
        for (int i = 0; i < pLen; ++i) {
            needs[p[i] - 'a']++;
        }
        vector<int> matched(26,0);
        int starP = 0;
        int endP = 0;
        vector<int> result;
        while (endP < pLen) {
            matched[s[endP] - 'a']++;
            endP++;
        }
        if (same(needs, matched)) {
            result.push_back(starP);
        }
        while (starP < sLen && endP < sLen) {
            matched[s[starP] - 'a']--;
            matched[s[endP] - 'a']++;
            starP++;
            endP++;
            if (same(needs, matched)) {
                result.push_back(starP);
            }
        }
        return result;
    }
private:
    /**
     *Determines whether the values in two arrays (within a given range) are equal
     * 
     * @param need Judgment reference array
     * @param matched Array to match each time
     * @return bool
     */
    bool same(vector<int>& need, vector<int>& matched) {
        for (int i = 0; i < need.size(); ++i) {
            if (need[i] != matched[i]) {
                return false;
            }
        }
        return true;
    }
};
  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值