问题描述
给你一个字符串 S、一个字符串 T 。请你设计一种算法,可以在 O(n) 的时间复杂度内,从字符串 S 里面找出:包含 T 所有字符的最小子串。
示例:
输入:S = "ADOBECODEBANC", T = "ABC"
输出:"BANC"
提示:
如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-window-substring
解答
class Solution { // public boolean check(){ // for(Map.Entry<Character, Integer> entry : ori.entrySet()){//entry遍历map // if(ori.get(entry.getKey()) > cnt.getOrDefault(entry.getKey(),0))return false; // } // return true; // } public boolean check() { Iterator iter = ori.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Character key = (Character) entry.getKey(); Integer val = (Integer) entry.getValue(); if (cnt.getOrDefault(key, 0) < val) { return false; } } return true; } Map<Character, Integer> ori = new HashMap<Character, Integer>(); Map<Character, Integer> cnt = new HashMap<Character, Integer>(); public String minWindow(String s, String t) { int tLen = t.length(); for (int i = 0; i < tLen; i++) { char c = t.charAt(i); ori.put(c, ori.getOrDefault(c, 0) + 1); } int l = 0, r = -1; int len = Integer.MAX_VALUE, ansL = -1, ansR = -1; int sLen = s.length(); while (r < sLen) { ++r; if (r < sLen && ori.containsKey(s.charAt(r))) { cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1); } while (check() && l <= r) { if (r - l + 1 < len) { len = r - l + 1; ansL = l; ansR = l + len; } if (ori.containsKey(s.charAt(l))) { cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1); } ++l; } } return ansL == -1 ? "" : s.substring(ansL, ansR); } }