算法76. Minimum Window Substring

76. Minimum Window Substring
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.

class Solution {
    public String minWindow(String s, String t) {
        
    }
}

给两个字符串S、T,找到 S 中包含 T 的最小窗口。要求复杂度小于等于 O(n)。
提示:
如果没有这样的窗口呢,就返回空字符。
如果有窗口,可以确定 S 中只有一个唯一的最小的窗口(就是不会存在相同长度的窗口)。

解:
不要求顺序,只要求包含,首先想到使用 set。这里有个陷阱,T 没说是否重复,所以可能是有重复的,所以要使用 map,存字符+数量。2个指针 l,r,都从0开始向末尾滑动,先 r++,直到找到包含全部 T 的字符且数量符合。然后在现有的 l-r 窗口中尝试找更小的子串,如果找不到更小子串,比如 l 都加到 r 的位置了,继续 r++,直到 l 和 r 都走到末尾。

以下为代码:

public String minWindow(String s, String t) {
    if (s.length() == 0 || t.length() == 0) {
        return "";
    }
        
        // 用于记录字符+数量
    Map dictT = new HashMap();
    for (int i = 0; i < t.length(); i++) {
        int count = dictT.getOrDefault(t.charAt(i), 0);
        dictT.put(t.charAt(i), count + 1);
    }
    
    // 满足要求不重复字符个数
    int required = dictT.size();

    int l = 0, r = 0;

    // 当前满足要求不重复字符个数
    int formed = 0;

        // 用于记录当前窗口的字符+数量
    Map windowCounts = new HashMap();
    // 记录解,三个数分别为长度、l、r
    int[] ans = { -1, 0, 0 };

    while (r < s.length()) {
        char c = s.charAt(r);
        int count = windowCounts.getOrDefault(c, 0);
        windowCounts.put(c, count + 1);

        if (dictT.containsKey(c) && windowCounts.get(c).intValue() == dictT
                .get(c).intValue()) {// 一个字符满足需求
            formed++;
        }

        while (l <= r && formed == required) {// 找到了一种解,尝试去找解中的子串
            c = s.charAt(l);

            if (ans[0] == -1 || r - l + 1 < ans[0]) {
                ans[0] = r - l + 1;
                ans[1] = l;
                ans[2] = r;
            }

            windowCounts.put(c, windowCounts.get(c) - 1);
            if (dictT.containsKey(c) && windowCounts.get(c)
                    .intValue() < dictT.get(c).intValue()) {
                formed--;
            }

            l++;
        }


        r++;
    }

    return ans[0] == -1 ? "" : s.substring(ans[1], ans[2] + 1);
}

你可能感兴趣的:(算法76. Minimum Window Substring)