【LeetCode】 Minimum Window Substring

来源:互联网 发布:android 打开数据连接 编辑:程序博客网 时间:2024/05/16 05:56

题目:

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).

For example,
S = "ADOBECODEBANC"
T = "ABC"

Minimum window is "BANC".

Note:
If there is no such window in S that covers all characters in T, return the empty string "".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

注意:

中间可以有间隔, 没有强调字符顺序

思路:

1. 将Target string 映射到一个数组里, 数组 dest[‘A’] = 3代表着字符‘A’出现了 三次。
2. 遍历Source String, 遍历时没有一个字符 就累加在数组 cur里面。
3. 假设 tmp 为当前遍历得到的字符,将 cur[tmp] ++, 则有以下几种情况:a 如果cur[tmp] > dest[tmp],说明当前字符 不在target 里面, 那么不做处理; b 若 cur[tmp] <= dest[tmp]则说明tmp 在target 里面, 那么我们将found++,作为找到一个target string 里面的字符。
这里要注意的是:我们有对重复字符做考虑,比如target string里出现了一次 ’A‘,在遍历source string 时, 当遇到第 二个 ‘A‘ 时, cur['A']  = 2 > dest['A'] = 1, 所以为们作为第一种情况处理。
4. 在遍历过程总, 当found = target.length, 说明我们找到了 target string 里面的所有字符。 于是我们要将现在的 begin 放在出现与target string 里 第一个 source string 中的字符。(这里感觉有点绕口, 但是仔细想一想,我们相当于把头指针放在第一个找到在target string 里面的字符上)。然后我们对minLen, end, 和begin 进行更新
5. 最后, 我们将第一个找到的字符, 也就是start位置上的字符往下移一个, 将找到的这个字符从咱们找到的 cur数组里删掉, 然后再继续遍历,相当于在滑动窗口。

代码:


public class Solution {    public String minWindow(String s, String t) {        int [] dest = new int[255];        //map the target string to an int array        for (int i = 0; i < t.length(); i ++){            dest[t.charAt(i)]++;        }                int minLen = s.length();//keep track of the minimum window        int begin = -1, end = 0, found = 0;        int start = 0;        int [] cur = new int [255];        for(int i = 0; i < s.length(); i ++){            char tmp = s.charAt(i);            cur[tmp]++;            if(cur[tmp] <= dest[tmp] )//the current char is inside the target string                found ++;            if(found == t.length()){//all of the string has been found            //find the start position of the first found char inside the source string                while(start < i && cur[(s.charAt(start))] > dest[s.charAt(start)]){                    cur[s.charAt(start)]--;                    start ++;                }                //update the begin, end and minLen                if(i - start <minLen){                    begin = start;                    end = i;                    minLen = i - start;                }                //take out the first found letter                cur[s.charAt(start)]--;                start++;                found --;            }        }        return begin == -1? "": s.substring(begin,end + 1);    }}