最小子串覆盖

107 阅读1分钟
S = "ADOBECODEBANC", T = "ABC";

        function minWindow(s,t) {

            let start = 0,end = 0, needMap = new Map(),match = 0,windowMap = new Map(),flag,tLen = t.length,sLen = s.length,minLen = sLen+1;

            // 缓存子串字符出现次数,不要求按顺序

            for(let i=0;i<tLen;i++){

                let val = needMap.get(t[i]);

                needMap.set(t[i],val ? ++val : 1);

            }

            while(end <= sLen){

                let val = windowMap.get(s[end]) ? windowMap.get(s[end]) : 0;

                windowMap.set(s[end],++val);

                val === needMap.get(s[end]) ? match++ : ''; //出现次数与子串出现次数一致,则代表start-end中对于包含子串中的该字符

                end++

                while(match === needMap.size) { //找到合适的子串判断条件,当子串所有的字符都被包含在start-end中

                    let val = windowMap.get(s[end]);

                    if(end - start < minLen) { // 找到窗口,缓存

                        minLen = end - start;

                        flag = start;

                    }

                    // 进行窗口缩小,从左开始,start--

                    let valStart = windowMap.get(s[start]);

                    if(valStart > 0) {

                        valStart--;

                        windowMap.set(s[start],valStart);

                        // 如果减去左边字符,规则还是满足则继续缩减,如不满足则取当前窗口进行滑动

                        needMap.get(s[start]) && valStart < needMap.get(s[start]) ? match-- : ''

                    }

                    start++

                }

            }

            return flag >=0 ? s.substr(flag,minLen) : ''

        }