Loading

LeetCode 76 最小覆盖范围

LeetCode76 最小覆盖范围

题目描述

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。

样例

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
输入:s = "a", t = "a"
输出:"a"

算法分析

  • 用两个哈希表来存储-
  • hs哈希表维护的是[j,i]区间中各个字符出现多少次,ht哈希表维护的是t字符串各个字符出现多少次
  • cnt维护的是s字符串[j,i]区间中满足t字符串的元素的个数
  • s[i]加入到hs中,同时观察s[j]是否多余,若多余则移出
  • 若hs[i] <= ht[i],表示多了一个符号的元素,cnt ++

时间复杂度

\(O(n)\)

Java代码

class Solution {
    public String minWindow(String s, String t) {
        HashMap<Character,Integer> hs = new HashMap<Character,Integer>();
        HashMap<Character,Integer> ht = new HashMap<Character,Integer>();
        for(int i = 0; i < t.length(); i ++){
            ht.put(t.charAt(i),ht.getOrDefault(t.charAt(i),0)+1);
        }
        String ans = "";
        int len = 0x3f3f3f3f;
        int cnt = 0;
        for(int i = 0, j = 0; i < s.length(); i ++){
            hs.put(s.charAt(i),hs.getOrDefault(s.charAt(i),0)+1);
            if(ht.containsKey(s.charAt(i)) && hs.get(s.charAt(i)) <= ht.get(s.charAt(i))){
                cnt ++;
            }

            while(j < i && (!ht.containsKey(s.charAt(j)) || hs.get(s.charAt(j)) > ht.get(s.charAt(j)))){
                int count = hs.get(s.charAt(j)) - 1;
                hs.put(s.charAt(j), count);
                j ++;
            }

            if(cnt == t.length() && i - j + 1 < len){
                len = i - j + 1;
                ans = s.substring(j,i+1);
            }
        }

        return ans;
    }
}
posted @ 2020-11-18 14:11  想用包子换论文  阅读(144)  评论(0)    收藏  举报