offer2-17


给定两个字符串 st 。返回 s 中包含 t 的所有字符的最短子字符串。如果 s 中不存在符合条件的子字符串,则返回空字符串 ""

如果 s 中存在多个符合条件的子字符串,返回任意一个。

注意: 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。

示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC" 
解释:最短子字符串 "BANC" 包含了字符串 t 的所有字符 'A'、'B'、'C'

示例 2:

输入:s = "a", t = "a"
输出:"a"

示例 3:

输入:s = "a", t = "aa"
输出:""
解释:t 中两个字符 'a' 均应包含在 s 的子串中,因此没有符合条件的子字符串,返回空字符串。

提示:

  • 1 <= s.length, t.length <= 105
  • st 由英文字母组成

进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?


//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public String minWindow(String s, String t) {
        if (s == null || s.length() == 0 || t == null || t.length() == 0) {
            return "";
        }
        int[] sArr = new int[52];
        int[] tArr = new int[52];

        for (char ch : t.toCharArray()) {
            if (ch <= 'Z') {
                tArr[ch - 'A']++;
            } else {
                tArr[26 + ch - 'a']++;
            }
        }

        int start = 0;
        int end = 0;
        int minLen = Integer.MAX_VALUE;
        String  result = "";

        while (end < s.length()) {
            while (end < s.length()) {
                char ch = s.charAt(end);

                if (ch <= 'Z') {
                    sArr[ch - 'A']++;
                } else {
                    sArr[26 + ch - 'a']++;
                }

                if (isMatch(sArr, tArr)) {
                    break;
                }
                end++;
            }

            if (end == s.length()) {
                break;
            }

            while (isMatch(sArr, tArr)) {
                if (end - start + 1 < minLen) {
                    minLen = end - start + 1;
                    result = s.substring(start, start + minLen);
                }
                char ch = s.charAt(start);
                if (ch <= 'Z') {
                    sArr[ch - 'A']--;
                } else {
                    sArr[26 + ch - 'a']--;
                }
                start++;
            }
            end++;
        }

        return result;
    }

    boolean isMatch(int[] sArr, int[] tArr) {
        for (int i = 0; i < 52; i++) {
            if (sArr[i] < tArr[i]) {
                return false;
            }
        }

        return true;
    }
}
//leetcode submit region end(Prohibit modification and deletion)

文章作者: 倪春恩
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 倪春恩 !