题解 | #寻找完成任务所需最短时间#

寻找完成任务所需最短时间

https://www.nowcoder.com/practice/107342346ad44329a35c7e5b890e7d40?tpId=354&tqId=10588489&ru=/exam/oj&qru=/ta/interview-202-top/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D354

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param s string字符串
     * @param t string字符串
     * @return string字符串
     */
    public String minWindow (String s, String t) {
        // write code here
        // 创建字符计数映射,记录 t 中每个字符出现的次数
        Map<Character, Integer> charCount = new HashMap<>();
        for (char c : t.toCharArray()) {
            charCount.put(c, charCount.getOrDefault(c, 0) + 1);
        }

        int left = 0; // 窗口左边界
        int minLen = Integer.MAX_VALUE; // 最小子串长度
        int minStart = 0; // 最小子串起始位置
        int requiredChars = t.length(); // 需要覆盖的字符数

        for (int right = 0; right < s.length(); right++) {
            char c = s.charAt(right);

            if (charCount.containsKey(c)) {
                if (charCount.get(c) > 0) {
                    requiredChars--;
                }
                charCount.put(c, charCount.get(c) - 1);
            }

            // 如果已经覆盖了 t 中所有字符
            while (requiredChars == 0) {
                // 更新最小子串信息
                if (right - left + 1 < minLen) {
                    minLen = right - left + 1;
                    minStart = left;
                }

                // 移动窗口左边界,尝试缩小子串
                char leftChar = s.charAt(left);
                if (charCount.containsKey(leftChar)) {
                    charCount.put(leftChar, charCount.get(leftChar) + 1);
                    if (charCount.get(leftChar) > 0) {
                        requiredChars++;
                    }
                }
                left++;
            }
        }

        if (minLen == Integer.MAX_VALUE) {
            return "";
        }

        return s.substring(minStart, minStart + minLen);
    }
}

知识点:

  1. 滑动窗口:通过维护一个窗口来滑动遍历字符串,从而找到符合条件的子串。
  2. 哈希映射(HashMap):用于存储字符串 t 中每个字符出现的次数,以及窗口中字符出现的次数。
  3. 双指针:使用左右指针来构建和移动滑动窗口。

解题思路:

使用滑动窗口的技巧来解决问题。我们维护两个指针 left 和 right 来表示窗口的左右边界。我们还使用了一个哈希映射来存储字符串 t 中每个字符出现的次数,以及窗口中字符出现的次数。

我们首先将右指针向右移动,不断更新窗口内字符的出现次数。当窗口内包含了所有 t 中的字符后,我们开始尝试缩小窗口,即移动左指针。通过不断缩小窗口,我们找到一个覆盖 t 中所有字符的最短子串。

全部评论

相关推荐

10-14 23:01
已编辑
中国地质大学(武汉) Java
CUG芝士圈:虽然是网上的项目,但最好还是包装一下,然后现在大部分公司都在忙校招,十月底、十一月初会好找一些。最后,boss才沟通100家,别焦虑,我去年暑假找第一段实习的时候沟通了500➕才有面试,校友加油
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务