Leetcode 最小覆盖子串

最小覆盖子串

题目描述:

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。
提示:
   1 <= s.length, t.length <= 10^5
   s 和 t 由英文字母组成

题目链接

class Solution {
    
    
    private String s;
    private String t;
    private Map<Character,Integer> index;
    private Map<Character,Integer> window;
    public String minWindow(String s, String t) {
    
    
        // 初始化
        int len = s.length();
        if(t.length()>len) return ""; // 特判
        if(len == 1){
    
    
            if(t.length() == 1 && s.charAt(0) == t.charAt(0)) return ""+s.charAt(0);
            else return "";
        }
        this.s = s;
        this.t = t;
        String result = "";
        this.index = new HashMap<Character,Integer>();
        this.window = new HashMap<Character,Integer>();

        for(int i = 0 ; i<t.length() ; i++){
    
    
            this.index.put(t.charAt(i),index.getOrDefault(t.charAt(i),0)+1);
        }
        // 双指针法
        int left = 0;
        int right = 0;
        int minLen = len;

        while(right<len){
    
    
            // 首先移动右指针直至找到一个包含所有t字符的子串
            while(right<len && !check()){
    
    
                window.put(s.charAt(right),window.getOrDefault(s.charAt(right),0)+1);
                right++;
            }
            // 其次移动左指针直至无法找到一个包含所有t字符串的子串
            while(check()){
    
    
                window.put(s.charAt(left),window.getOrDefault(s.charAt(left),0)-1); // 负数不会影响结果
                left++;
            }
            // 处理
            if(minLen >= (right-left+1)){
    
    
                minLen = right-left+1;
                result = s.substring(left-1,right);// left-1到right的子串
            }
        }
        return result;
    }
    private boolean check(){
    
    
        Iterator iter = index.entrySet().iterator(); 
        while (iter.hasNext()) {
    
     
            Map.Entry entry = (Map.Entry) iter.next(); 
            Character key = (Character) entry.getKey(); 
            Integer val = (Integer) entry.getValue(); 
            if (window.getOrDefault(key, 0) < val) {
    
    
                return false;
            }
        } 
        return true;
    }
}

该题利用双指针法,首先移动右指针,直到找到某一段s字符串含有t字符串所有字符的才停止移动,然后移动左指针,直到不满足该段s字符串中含有t字符串所有字符才停止移动,整个操作重复以上步骤,每次记录最小的result和最小长度。这里主要的难点就是:如何才能判断t字符串元素都包含在某一段s字符串中的所有元素中,笔者初次使用数组,发现卡在最后一个数据集,超时了,然后借鉴了官方的题解,利用HashMap结构,才通过的。详细请看代码,读者有疑问欢迎留言。

猜你喜欢

转载自blog.csdn.net/weixin_43914658/article/details/113811936
今日推荐