双指针(滑动窗口)

题目在这里

概述:给定s,p两字符串,在s串中找p的异位串的所有起始下标

常规思路:

  由于是小写字母构成的字符串,那么用前缀和sum迭代统计p.len长度的字母,再与p字符串的桶存数组比较即是ans

class Solution
{
public:
    vector<int> findAnagrams(string s, string p)
    {
        vector<vector<int>> sum(s.length(), vector<int>(30, 0));
        vector<int> ans;
        int ls = s.length(), lp = p.length();
        vector<int> sp(30, 0);
        for (auto i : p)
            sp[i - 'a']++;
        for (int i = 0; i < ls; ++i)
        {
            for (int j = 'a' - 'a'; j <= 'z' - 'a' && i > 0; j++)
                sum[i][j] = sum[i - 1][j];
            if (i >= lp)
                sum[i][s[i - lp] - 'a']--;
            sum[i][s[i] - 'a']++;
            if (i + 1 >= lp && sum[i] == sp)
                ans.emplace_back(i - lp + 1);
        }
        return ans;
    }
};
normal

但是常规归常规,复杂度为O(s.len+(s.len-p.len)*Σ),Σ=26

一般般,

故而进取之,

思路:

  还是桶存p字符串的字母,在遍历s字符串中用l,r左右端点去维护这个桶的字母数,

  当桶的长度满足p串长度,也即r-l+1==p.len时候,那么一定有l位置是异位串的起始下标。

code:

class Solution
{
public:
    vector<int> findAnagrams(string s, string p)
    {
        vector<int> sum(30, 0), ans;
        int ls = s.length(), lp = p.length();
        if (ls < lp)
            return ans;
        for (auto i : p)
            sum[i - 'a']++;
        for (int l = 0, r = 0; r < ls; ++r)
        {
            --sum[s[r] - 'a'];
            while (sum[s[r] - 'a'] < 0)
                ++sum[s[l++] - 'a'];
            if (r - l + 1 == lp)
                ans.emplace_back(l);
        }
        return ans;
    }
};
天秀

 

【Over】

posted @ 2022-03-15 20:47  Renhr  阅读(41)  评论(0)    收藏  举报