Javascript sliding window + hashmap 1994ms
\nconst addOneOrManyMap = (m, x, cnt = 1) => m.set(x, m.get(x) + cnt || cnt);\nconst removeOneOrManyMap = (m, x, cnt = 1) => { let occ = m.get(x); occ > cnt ? m
```\nconst addOneOrManyMap = (m, x, cnt = 1) => m.set(x, m.get(x) + cnt || cnt);\nconst removeOneOrManyMap = (m, x, cnt = 1) => { let occ = m.get(x); occ > cnt ? m.set(x, occ - cnt) : m.delete(x); };\nconst counter = (a_or_s) => { let m = new Map(); for (const x of a_or_s) m.set(x, m.get(x) + 1 || 1); return m; };\nconst ord = (c) => c.charCodeAt();\n\nconst countCompleteSubstrings = (s, k) => {\n    let l = 0, res = 0, n = s.length;\n    for (let i = 1; i < n; i++) {\n        if (Math.abs(ord(s[i]) - ord(s[i - 1])) > 2) {\n            res += cal(s.slice(l, i), k);\n            l = i;\n        }\n    }\n    res += cal(s.slice(l), k);\n    return res;\n};\n\n\nconst cal = (s, k) => {\n    let res = 0, n = s.length;\n    for (let i = 1; i <= 26; i++) {\n        if (i * k > n) break;\n        let l = i * k, f = counter(s.slice(0, l)), ff = counter(f.values());\n        if (ff.get(k) == i) res++;\n        for (let j = 0; j < n - l; j++) {\n            removeOneOrManyMap(ff, f.get(s[j]));\n            removeOneOrManyMap(f, s[j]);\n            addOneOrManyMap(ff, f.get(s[j]));\n\n            removeOneOrManyMap(ff, f.get(s[j + l]));\n            addOneOrManyMap(f, s[j + l]);\n            addOneOrManyMap(ff, f.get(s[j + l]));\n\n            if (ff.get(k) == i) res++;\n        }\n    }\n    return res;\n};\n```
['Hash Table', 'Sliding Window', 'JavaScript']