美文网首页
Minimum Window Substring

Minimum Window Substring

作者: 瞬铭 | 来源:发表于2019-09-25 14:53 被阅读0次

https://leetcode.com/problems/minimum-window-substring/
给定两个字符串s和t,求出一个s中的最小子串,是这个子串包含t中的所有字符

例子:s="ADOBECODEBANC" t="ABC"

 public String minWindow(String s, String t) {
        String res = "";
        HashMap<Character, Integer> letterCnt = new HashMap<Character, Integer>();
        int left = 0, cnt = 0, minLen = Integer.MAX_VALUE;

        //计算t中char的个数,并存入HashMap  letterCnt
        for (int i = 0; i < t.length(); i++) {
            if (letterCnt.containsKey(t.charAt(i))) {
                letterCnt.put(t.charAt(i), letterCnt.get(t.charAt(i)) + 1);
            } else {
                letterCnt.put(t.charAt(i), 1);

            }
        }

        for (int i = 0; i < s.length(); i++) {
            char tmp = s.charAt(i);

            if (!letterCnt.containsKey(s.charAt(i))) {
                continue;
            }

            //letterCnt中包含是该char,才继续往下走
            letterCnt.put(tmp, letterCnt.get(tmp) - 1);
            if (letterCnt.get(tmp) >= 0) {
                cnt++;
            }

            //解释:当cnt达到了t的长度,left和i中间夹的这个子串一定包含t,

            while (cnt == t.length()) {
                char tmp1 = s.charAt(left);
                //此时又分两种情况,
                // 情况一:
                // left的是在letterCnt中的:此时要做一波判断,i和left的中间子集是否是最小集
                // (可以断定,最小集的时候,left对应的的值一定在letterCnt中)
                if (letterCnt.containsKey(tmp1)) {
                    if (minLen > i - left + 1) {
                        minLen = i - left + 1;
                        res = s.substring(left, minLen + left);
                    }

                    //这句话有点意思,这句话是为了中和left++
                    //因为此时left在letterCnt中已经存在了,而这段代码往下执行,left一定会往右滑一个
                    //滑完之后,letterCnt中就少了一个tmp1,所以这里先加上
                    letterCnt.put(tmp1, letterCnt.get(tmp1) + 1);
                    //小tips  letterCnt的值有可能为负,但是不影响结果~

                    //这段代码翻译就是,我即将右滑(left++),滑掉的这个字符,刚好是匹配上的,所以cnt要减1
                    //talk is cheap ,例子:
                    //s=ADOBECODEBANC,t=ABC
                    //当left=0,i=5的时候,res为"ADOBEC",这是下次要把第一个A滑走了~
                    // 所以到这里的时候letterCnt['A'] = 1(因为上一步+1了),所以当下一步left++后,相当于i和left之间没有A了~
                    //所以cnt要减1
                    if (letterCnt.get(tmp1) > 0) {
                        //当letterCnt里面还有这个字符的时候,表明还有未匹配的char(还需要在t中找相关的char)
                        cnt--;
                    }
                }

                // 情况二:left不在letterCnt中,所以不用判断,最小集的更改,因为此时一定不是最小集
                // (you ask me why? I tell you think about it yourself)此时用left直接向右边滑动

                //所以不管left在不在letterCnt中,left都要向右滑
                left++;//flag1
            }
        }
        return res;
    }

相关文章

网友评论

      本文标题:Minimum Window Substring

      本文链接:https://www.haomeiwen.com/subject/ojlsyctx.html