面试题17:包含所有字符的最短字符串

题目:输入两个字符串s和t,请找出字符串s中包含字符串t的 所有字符的最短子字符串。例如,输入的字符串s为"ADDBANCAD", 字符串t为"ABC",则字符串s中包含字符’A’、'B’和’C’的最短子字 符串是"BANC"。如果不存在符合条件的子字符串,则返回空字符串""。如果存在多个符合条件的子字符串,则返回任意一个。

// 利用哈希表和双指针来解题
public String minWindow(String s, String t) {
    HashMap<Character, Integer> charToCount = new HashMap<>();
    // 将t中出现的字符及其出现的次数存储到哈希表中
    for (char ch : t.toCharArray()) {
        charToCount.put(ch, charToCount.getOrDefault(ch, 0) + 1);
    }
    // count当前为字符串t中出现的字符种类数
    int count = charToCount.size();
    int minStart = 0, minEnd = 0, start = 0, end = 0;
    int minLength = Integer.MAX_VALUE;
    // 当end小于s字符串的长度时
    // 或者count == 0并且end等于s字符串的长度时
    // (因为如果count > 0的话会s.charAt(end)会超出索引范围
    // 所以count == 0 和 end == s.length()需要同时满足)
    while (end < s.length() || (count == 0 && end == s.length())) {
        // 当count大于0的时候同时也是end < s.length()的时候end指针向右移动
        if (count > 0) {
            char endCh = s.charAt(end);
            // 如果当前的字符在哈希表中存在, 则将哈希表中该字符对应的值减一
            if (charToCount.containsKey(endCh)) {
                charToCount.put(endCh, charToCount.get(endCh) - 1);
                // 经过上面的减一操作如果在哈希表中当前字符的值为零了
                // 则将count的值减一(表示s的子字符串中已经满足了存在对应个数该字符的条件)
                if (charToCount.get(endCh) == 0) {
                    count--;
                }
            }
            // end指针右移
            end++;
        // 因为count始终是大于等于零的所以此时的条件等价为count == 0,
        // 即s中的子字符串满足了包含t中的所有字符,此时start指针右移
        } else {
            // end - start < minLength
            // 即字符串之间的长度小于最小的长度
            if (end - start < minLength) {
                minLength = end - start;
                minStart = start;
                minEnd = end;
            }
            // startCh为start指针所对应的字符
            char startCh = s.charAt(start);
            // 如果哈希表中存在startCh这个字符
            if (charToCount.containsKey(startCh)) {
                // 因为start指针右移,则hash表中对应值加一
                charToCount.put(startCh, charToCount.get(startCh) + 1);
                // 如果哈希表中对应字符的值再经过上一步操作由0变为1了
                // 则将count的值加一(表示s的子字符串中不满足了存在对应个数该字符的条件)
                if (charToCount.get(startCh) == 1) {
                    count++;
                }
            }
            // start指针右移
            start++;
        }
    }
    return minLength < Integer.MAX_VALUE ? s.substring(minStart, minEnd) : "";
}

你可能感兴趣的:(剑指office(Java版),java,哈希算法,开发语言)