Sliding window + Map
\n\n# Code\ntypescript []\nfunction match(w1: Map<string, number>, w2: Map<string, number>){\n    return [...w2.keys()].every(w2char => w1.get(w2char) >= w2.get
\n\n# Code\n```typescript []\nfunction match(w1: Map<string, number>, w2: Map<string, number>){\n    return [...w2.keys()].every(w2char => w1.get(w2char) >= w2.get(w2char))\n}\n\nfunction validSubstringCount(word1: string, word2: string): number {\n    const w2Freq = new Map()\n    const w1WindowFreq = new Map()\n    let count = 0\n    word2.split(\'\').forEach(char => w2Freq.set(char, (w2Freq.get(char) ?? 0) + 1))\n    word1.slice(0, word2.length).split(\'\').forEach(char => w1WindowFreq.set(char, (w1WindowFreq.get(char) ?? 0) + 1))\n    \n    let windowStart = 0, windowEnd = word2.length - 1;\n    for(windowEnd; windowEnd < word1.length;) {\n        if(match(w1WindowFreq, w2Freq)) {\n            count += word1.length - windowEnd\n            // shrink the window & remove the item on windowStart\'s index\n            w1WindowFreq.set(word1[windowStart], w1WindowFreq.get(word1[windowStart]) - 1)\n            if(w1WindowFreq.get(word1[windowStart]) <= 0) {\n                w1WindowFreq.delete(word1[windowStart])\n            }\n            windowStart++\n        } else {\n            // increase window if theres no match\n            windowEnd++\n            w1WindowFreq.set(word1[windowEnd], (w1WindowFreq.get(word1[windowEnd]) ?? 0) + 1)\n        }\n    }\n\n    return count\n};\n```
['TypeScript']