• 不定長的 Sliding Window 套 pattern
class IWindow {
public:
    virtual void add(char& c) = 0;
    virtual void erase(char& c) = 0;
    virtual bool check(char& c) = 0;
    virtual ~IWindow() {}
};

class Window: public IWindow{
private:
    int cnt[26];
public:
    Window() {
        memset(cnt, 0, sizeof(cnt));
    }
    void add(char& c) override {
        cnt[c-'a']++;
    }
    void erase(char& c) override {
        cnt[c-'a']--;
    }
    bool check(char& c) override {
        return cnt[c-'a'] == 2;
    }
};

class Solution {
private:
    unique_ptr<IWindow> _w;
public:
    Solution(): _w(make_unique<Window>()) {}
    int maximumLengthSubstring(string s) {
        int n = s.size(), left = 0, right = 0;
        int res = 0;
        while (right < n) {
            char c = s[right++];
            while (_w->check(c)) _w->erase(s[left++]);
            _w->add(c);
            res = max(res, right-left);
        }   
        return res;
    }
};