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

问题:

已知字符串S与字符串T,求在S中的最小窗口(区间),使得这个区间中包含了字符串T中的所有字符。

思路:

1、设置两个字符哈希数组,map_s与map_t,map_s代表当前处理的窗口区间中的字符数量,map_t代表子串中T的字符数量。

2、设置两个指针(begin与i)指向字符串第一个字符。

3、i指针向后逐个扫描字符串中的字符,在此过程中,循环检查begin指针是否可以向前移动:

向前移动条件:

1)begin指向了没有在T中出现的字符

2) 指向的字符出现在T中,但窗口中有超过T中该字符个数的字符

4、指针i每次向前扫描一个字符,即检查一下是否可以更新最终结果。

整个过程中,begin与i共同维护一个窗口,该窗口的子串满足题目条件(包含T中所有字符),窗口线性向前滑动,整体时间复杂度为O(N)。

Leetcode提交通过,但是运行了1056ms, 时间好像比较久。

class Solution {
    public String minWindow(String s, String t) {
        String result = "";
        if(s == null || t == null || s.length() == 0 || t.length() == 0 ) 
            return result;
        int begin = 0;
        int[] map_s = new int[256];
        int[] map_t = new int[256];
        for(int i=0;i<t.length();i++)
        {
            map_t[t.charAt(i)]++;
        }
        for(int i=0; i<s.length(); i++)
        {
            map_s[s.charAt(i)]++;
            while(begin<i){
            if(map_t[s.charAt(begin)]==0) //若字符串t中没有该字符
                begin++;
            else if(map_s[s.charAt(begin)]>map_t[s.charAt(begin)]) //若字符串s中该字符数量>t中该字符数量
            {
                map_s[s.charAt(begin)]--;
                begin++;
            } 
            else
                break;
            }
            if(is_window_ok(map_s,map_t,t))
            {
             int len = i-begin+1;
                if(result=="" || result.length() > len)
                    result = s.substring(begin,i+1);
            }        
        } 
        return result;
    }
    private boolean is_window_ok(int[] map_s, int[] map_t, String t)
    {
        for(int i=0;i<t.length();i++)
        {
            if(map_s[t.charAt(i)]<map_t[t.charAt(i)])
                return false;
        }
        return true;
    }
}
博主学习笔记,转载请注明出处,谢谢~   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值