LeetCode刷题笔记-76

LeetCode-76. Minimum Window Substring(Hard):

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

Example:

Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"

Note:

  • If there is no such window in S that covers all characters in T, return the empty string "".
  • If there is such window, you are guaranteed that there will always be only one unique minimum window in S.

网上解法:

这道题使用滑动窗口的方法,用到哈希表记录匹配信息,由于这道题比较典型我直接找合理的方法了,特别记录一下。

整体思路是这样的:用hash表记录T中每一个字母出现的次数,用hash表的好处是不用遍历可以直接通过键值查找。设置一个计数器count,然后遍历S,如果当前字母是T中有的字母,则查看hash表中记录的该字母出现的次数是否不为零,不为零则将该字母的记录次数减1,同时count+1,每次判断完当前位置的字母后,检查计数器count是否达到T的长度,达到则判断当前子串长度是否小于记录的最小长度。然后窗口左边界右移,直到越过一个T中包含的字母,越过之后判断该字母的hash记录是否>=0,如果>=0则count--(这个位置就比较关键了,hash表中记录的次数可能是负的,-1代表该字母在当前窗口中出现的次数比T中应该出现的次数多了一次,也就是说即使窗口左移越过该字母,count也不需要减,因为当前窗口中该字母的出现次数是够的,这里就是该代码最巧妙的部分)

看完这个代码觉得自己还差得远,想问题还是比较粗略。

class Solution {
    public String minWindow(String s, String t) {
        String string = "";
        //hashmap来统计t字符串中各个字母需要出现的次数
        HashMap map = new HashMap<>();
        for (char c : t.toCharArray())
            map.put( c, map.containsKey(c) ? map.get(c)+1 : 1);
        //用来计数 判断当前子字符串中是否包含了t中全部字符
        int count = 0;
        //记录当前子字符串的左右下标值
        int left = 0;
        int right = 0;
        //记录当前最小子字符串的大小以及第一最后字符的下标值
        int min = Integer.MAX_VALUE;
        int minLeft = 0;
        int minRight = 0;
        for (; right < s.length() ; right++) {
            char temp = s.charAt(right);
            if (map.containsKey(temp)){//向后遍历出所包含t的字符串
                count = map.get(temp) > 0 ? count+1 : count;
                map.put(temp,map.get(temp)-1);
            }
            while (count == t.length()){//得出一个符合条件的子字符串
                if (right-left < min){//更新min minLeft minRight 信息
                    min = right - left;
                    minLeft = left;
                    minRight = right;
                }
                char c = s.charAt(left);
                if (map.containsKey(c)){//向左收缩 判断所删减的字符是否在map中
                    if (map.get(c) >= 0)count --;//count--时需要判断一下是否需要-- 
                    map.put(c,map.get(c)+1);
                }
                left++;
            }
        }
        return min == Integer.MAX_VALUE ?  "" : s.substring(minLeft,minRight+1);
    }
}

 

你可能感兴趣的:(LeetCode)