• 難度分: 2449
  • 這題是一個定長的 sliding window,比較難想的是 window size 是 k * 1, k * 2, … 到 k * 26,因為只有 26 個英文字母,所以最多只可能到 26 * k 的長度。
  • 額外需要檢查相鄰的字母是否距離 <= 2,我使用的方法是找到一個 j 記錄最大的不符合的索引值,所以直要 window 不包含該 j,window 內的所字元都會滿足。
  • 所以 pesudo code 會是
    for (int c = 1; c <= 26; i++) {
        // window size
        int windowSize = c * k;
        // construct window
        for (int i = 0; i < windowSize; i++) {
            // 處理 j
            // 計算進入 window
        }
    
        // 確認初始的 window 是否滿足
    
        // rolling windo
        for (int i = windowSize; i < n; i++) {
            // 處理 j
            // 計算進入 window
            // 計算離開 window
    
            // 確認 window 是否滿足
        }
    }
    
class Solution {
public:
    int countCompleteSubstrings(string s, int k) {
        int n = s.size();
        int res = 0;
        for (int idx = 1; idx <= 26 && idx * k <= n; idx++) {
            int len = idx * k;
            int j = -1;
            vector<int> cnt(26, 0);
            int valid = 0;
            for (int i = 0; i < len; i++) {
                if (i > 0 && abs(s[i] - s[i-1]) > 2) {
                    j = i-1;
                }
                if (++cnt[s[i]-'a'] == k) valid++;
            }
            if (valid == idx && j < 0) {
                res++;
            }

            for (int i = len; i < n; i++) {
                if (abs(s[i] - s[i-1]) > 2) {
                    j = i-1;
                }
                if (++cnt[s[i]-'a'] == k) valid++;
                if (cnt[s[i-len]-'a']-- == k) valid--;
                if (valid == idx && i-len >= j) {
                    res++;
                }
            }
        }
        return res;
    }
};