LeetCode 438 Find All Anagrams in a String

344 阅读1分钟

LeetCode 438 Find All Anagrams in a String

思路

  1. 长度不固定的滑动窗口。map统计目标串中,各字符的频率。counter表示在begin至end的范围内,目标串中所含字符所对应的频率大于0的字符个数。

  2. 固定长度的滑动窗口

代码

方法1

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int length = p.size();
        if (s.empty() || s.size() < length) return {};
        
        vector<int> rs;
        unordered_map<int, int> mp;
        for (const auto &ch : p)
            ++mp[ch];
        
        int counter = mp.size();
        
        for (int begin = 0, end = 0; end < s.size(); ++end) {
            if (mp.count(s[end])) {
                --mp[s[end]];
                if (!mp[s[end]]) --counter;
            }
            
            while (!counter) {
                if (end - begin + 1 == length) 
                    rs.push_back(begin);
                
                if (mp.count(s[begin])) {
                    ++mp[s[begin]];
                    if(mp[s[begin]] > 0) 
                        ++counter;
                }
                
                ++begin;
            }
        }
        
        return rs;
    }
};

方法2

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        if (s.empty() || p.size() > s.size()) return {};
        vector<int> pFreq(26, 0), sFreq(26, 0), rs;
        
        for (int i = 0; i < p.size(); ++i) {
            ++pFreq[p[i] - 'a'];
            ++sFreq[s[i] - 'a'];
        }
        
        if (compare(pFreq, sFreq)) rs.push_back(0);
        
        for (int i = p.size(); i < s.size(); ++i) {
            char front = s[i - p.size()], back = s[i];
            --sFreq[front - 'a'];
            ++sFreq[back - 'a'];
            if (compare(pFreq, sFreq))
                rs.push_back(i - p.size() + 1);
        }
        
        return rs;
    }
    
    bool compare(vector<int> &a, vector<int> &b) {
        for (int i = 0; i < a.size(); ++i) {
            if (a[i] != b[i]) return false;
        }
        
        return true;
    }
};