LeetCode OJ算法题(七十六):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).

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 emtpy string "".

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

解法:

首先将T变成一个字典,用HashMap存储,key为字符,value为该字符的个数。

用start指向S中窗口的开始位置,end指向窗口的结尾位置,初始值为0,开始遍历end

当遇到T中的字符时,将该字符的计数减一,如果剩余数大于等于0,说明是一个有用的字符,如果小于0说明这个字符已经太多了。我们设置一了记录有用字符个数的计数器count,如果count等于T的长度时,就说明这是一个有效的窗口,但是这个窗口不一定是最优的,因为可能包含不需要的T中字符。、

这个时候我们就可以移动start指针,当start指向一个T中字符,判断它是否是多余的,如果不是,那么这个窗口就是一个局部最优解,如果是多余的,start就继续右移(不会超过end的)。

当找到一个局部最优解后,就可以继续移动end指针。以此类推,直到end移动到S末尾。

最后,我们只用在所有局部最优解中找到最优的即可,整个算法时间复杂度为O(2n+m)

import java.util.HashMap;

public class No76_MinimumWindowSubstring {
	public static void main(String[] args){
		System.out.println(minWindow("ADOBECODEBANC", "ABC"));
		System.out.println(minWindow("AADBCAB", "ABC"));
		System.out.println(minWindow("", ""));
	}
	public static String minWindow(String S, String T) {
        HashMap<Character, Integer> map = new HashMap<Character, Integer>();
        for(int i=0;i<T.length();i++){
        	char c = T.charAt(i);
        	if(map.get(c) == null)
        		map.put(c, 1);
        	else
        		map.put(c, map.get(c)+1);
        }
        int start = 0;
        int end = 0;
        int count = 0;
        int maxlen = S.length()+1;
        String ret = "";
        for(;end<S.length();end++){
        	char c = S.charAt(end);
        	if(map.containsKey(c)){
        		map.put(c, map.get(c)-1);
        		if(map.get(c) >= 0) count++;
        		while(count == T.length()){
        			if(map.containsKey(S.charAt(start))){
        				map.put(S.charAt(start), map.get(S.charAt(start))+1);
        				if(map.get(S.charAt(start)) > 0){
        					if(maxlen > end-start+1){
        						ret = S.substring(start, end+1);
        						maxlen = end-start+1;
        					}
        					count--;
        				}
        			}
        			start++;
        		}
        	}
        }
        return ret;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值