hot100----滑动窗口

54 阅读1分钟

无重复字符的最长子串(leetcode.3)

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        // 依次遍历字符串的每个元素,找包括这个元素的之后的连续不重复子串,最终返回最长子串即可
        // 滑动窗口
        unordered_set<char> occ;
        int n = s.size();
        int r = -1,ans = 0;
        // 枚举左边界位置,也就是字符串的每个元素
        for(int i = 0; i < n; i++){
            // 一开始左边界不用动,先动右边界直到遇到重复字符
            if(i != 0){
                // 第一个滑动窗口结束后,左边界就可以开始移动了
                occ.erase(s[i-1]);
            }
            // 不断扩展右边界
            while(r + 1 < n && !occ.count(s[r+1])){
                // 将不重复的字符存入occ
                occ.insert(s[r+1]);
                r++;
            }
            ans = max(ans,r-i+1);
        }
        return ans;
    }
};

找到字符串所有字母异位词(leetcode.438)

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int sLen = s.size(),pLen = p.size();

        if(sLen < pLen){
            return vector<int>();
        }

        vector<int> ans;
        vector<int> sCount(26);
        vector<int> pCount(26);

        // 第一个滑动窗口,从下标为0开始,滑动窗口长度为p的长度
        for(int i = 0; i < pLen; ++i){
            ++sCount[s[i]-'a'];
            ++pCount[p[i]-'a'];
        }

        // 如果第一个滑动窗口就是异位词,将下标0存入结果数组
        if(sCount == pCount){
            ans.emplace_back(0);
        }

        // 同时扩展左边界和右边界,因为要求是连续的
        for(int i = 0;i < sLen - pLen; ++i){
            --sCount[s[i]-'a']; //左边界移除一个元素
            ++sCount[s[i+pLen]-'a']; //右边界添入一个元素

            if(sCount == pCount){
                ans.emplace_back(i+1);
            }
        }
        return ans;
    }
};