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.

思路:

1. 维护一个map<Character, Integer>来表示每个字母还可以出现的次数。开始的时候建立map,字母对应在target string里出现的次数。另外一个count

2. 对长sring扫描,如果遇到map里存在的字母,就对对应的值-1 (注意这里可以是负数,表示该位字母出现多次,但是我们不计算在总count里).如果该值>=0则总count++,表示总共找到的字母增加一位。

3. 如果count = target.length()说明已经全部找到,这时窗口左边向右移动,如果对应的值在map里,那就把map里的value+1,因为我们需要寻找的字母又少了一个。在value+1后,如果count<target.length(),说明我们又可以开始寻找下一个了,就先计算一下当前match的长度:right-left+1

    public String minWindow(String S, String T) {
        if (T.length() == 0) {
            return "";
        }
        int count = 0;
        Map<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 minLen = Integer.MAX_VALUE;
        String result = "";
        int left = 0, right = 0;
        while (left <= S.length() - T.length() && right < S.length()) {
            if (map.containsKey(S.charAt(right))) {
                map.put(S.charAt(right), map.get(S.charAt(right))-1);
                if (map.get(S.charAt(right)) >= 0) {
                    count++;
                }
                while (count == T.length()) {
                    if (map.get(S.charAt(left)) != null) {
                        map.put(S.charAt(left), map.get(S.charAt(left))+1);
                        if (map.get(S.charAt(left)) > 0) {
                            int curLen = right-left+1;
                            if (curLen < minLen) {
                                minLen = Math.min(minLen, curLen);
                                result = S.substring(left, right+1);
                            }
                            count--;
                        }
                    }
                    left++;
                }
            }
            right++;
        }

        return result;
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值