包含所有字符的最短字符串

        由题还是很容易想到可以用一个哈希表来统计字符串中每个字符出现的次数。首先扫描字符串t,每扫到一个,哈希表中对应值加1。然后扫描字符串s,每扫描一个就检查哈希表中是否包含该字符,没有则忽略不计。如果存在,对应的值减1。所有如果字符串s包含字符串t的所有字符,那么哈希表中的所有的值应该都小于或等于0。

        还是维护一个滑动窗口,某一时刻两指针间子字符串还没包含字符串t的所有字符,则移动右指针添加新的字符,如果还没有则继续移动右指针。

        某一时刻两指针间子字符串已经包含字符串t的所有字符,因为目标是找出最短符合条件的子字符串,所有移动左指针,然后判断删除最左边的字符后是否仍包含字符串t的所有字符。

    public String minWindow(String s, String t) {
        // 创建一个HashMap,用于存储字符串 t 中每个字符的出现次数
        // 因为用HashMap很方便判断一个字符是否在字符串t中出现
        // 所有没有用数组去模拟哈希表
        HashMap<Character, Integer> charToCount = new HashMap<>();

        // 遍历字符串 t,将每个字符及其出现次数存入HashMap
        for (char ch : t.toCharArray()) {
            charToCount.put(ch, charToCount.getOrDefault(ch, 0) + 1);
        }

        // 初始化计数器,表示还需要找到的字符个数
        int count = charToCount.size();

        // 初始化左、右指针和最小窗口的起始和结束位置
        int start = 0, end = 0, minStart = 0, minEnd = 0;

        // 初始化最小窗口的长度为整数最大值
        int minLength = Integer.MAX_VALUE;

        // 开始遍历字符串 s
        while (end < s.length() || (count == 0 && end == s.length())) {
            if (count > 0) {
                // 如果还有字符未找到
                // 取得当前指针处的字符
                char endCh = s.charAt(end);

                // 如果该字符在字符串 t 中存在
                if (charToCount.containsKey(endCh)) {
                    // 更新HashMap中该字符的出现次数
                    charToCount.put(endCh, charToCount.get(endCh) - 1);

                    // 如果出现次数减至零,表示该字符已找到足够次数
                    if (charToCount.get(endCh) == 0) {
                        count--;
                    }
                }

                // 移动指针
                end++;
            } else {
                // 如果所有字符都已找到
                // 计算当前窗口的长度
                if (end - start < minLength) {
                    minLength = end - start;
                    minStart = start;
                    minEnd = end;
                }

                // 取得当前指针处的字符
                char startCh = s.charAt(start);

                // 如果该字符在字符串 t 中存在
                if (charToCount.containsKey(startCh)) {
                    // 更新HashMap中该字符的出现次数
                    charToCount.put(startCh, charToCount.get(startCh) + 1);

                    // 如果出现次数增至1,表示还需要找到该字符
                    if (charToCount.get(startCh) == 1) {
                        count++;
                    }
                }

                // 移动指针
                start++;
            }
        }

        // 返回最小窗口子串,如果没有找到则返回空字符串
        return minLength < Integer.MAX_VALUE ? s.substring(minStart, minEnd) : "";
    }

        下面是对代码的一个详细解释(因为是Hard难度所以再借助AI全面阐述一遍)

  1. 初始化HashMap: 代码一开始创建了一个HashMap charToCount,用于存储字符串 t 中每个字符的出现次数。

  2. 遍历字符串 t 程序首先遍历字符串 t,将其中每个字符及其出现的次数存储在 charToCount 中。

  3. 初始化变量: 初始化了一些变量,包括计数器 count(表示还需要找到的字符个数)、指针 startend(用于构建窗口)、以及用于记录最小窗口的起始和结束位置的变量 minStartminEnd,同时也初始化了记录最小窗口长度的变量 minLength 为整数最大值。

  4. 使用滑动窗口算法: 在这段代码中,通过滑动窗口算法来寻找符合条件的最小窗口子串。

  5. 遍历字符串 s 使用 while 循环遍历字符串 s,其中 end 指针不断向右移动。

  6. 找到包含 t 中所有字符的窗口:

    • count > 0 时,表示还有字符未找到。程序会检查当前 end 指向的字符是否在字符串 t 中,如果是,更新该字符在 charToCount 中的计数,当某个字符的计数减为零时,count 减一,表示找到了一个字符。
    • 一旦 count 减至零(意味着已经找到了所有 t 中的字符),代码会执行 else 部分,这时会计算当前窗口的长度,并与之前记录的最小长度进行比较。
    • 如果当前窗口的长度更小,则更新最小长度 minLength,同时记录当前窗口的起始和结束位置 minStartminEnd
    • start 指针向右移动,并且对应字符在 charToCount 中的计数也会相应地更新,直到 count 不再为零。
  7. 返回结果: 最后,根据 minLength 是否被更新过来判断是否找到了包含 t 中所有字符的最小窗口子串。如果找到了,返回该子串;否则返回空字符串。

  • 28
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 字符串化算法的目的是尽可能地减少字符串的长度,通常通过在字符串中寻找重复的子串并将其压缩来实现。 常见的字符串化算法包括哈夫曼编码和字典压缩算法。 哈夫曼编码是一种统计学编码方法,它可以有效地压缩字符串。哈夫曼编码的基本思想是,将出现频率最高的字符用最的二进制编码表示,而出现频率较低的字符用较长的二进制编码表示。这样可以最大限度地减少字符串的长度。 字典压缩算法是一种把字符串中的重复子串压缩成一个的字典编码的方法。这种算法通常使用一个字典来保存所有出现过的子串,并为每个子串分配一个唯一的编码。当遇到重复的子串时,可以使用该子串的编码来代替原始子串,从而达到压缩字符串的目的。 总的来说,字符串化算法可以有效地减少字符串的长度,并且在很多场景下都很有用,例如在数据压缩和数据传输中。但是,它们的时间复杂度 ### 回答2: 最字符串的算法分析,可以参考以下思路: 假设有一个字符串字典,存储了一系列的字符串。我们需要找到其中最字符串。 一种简单的方法是遍历整个字符串字典,在遍历过程中记录当前最字符串。具体过程如下: 1. 初始化一个变量min_str为一个较大值,表示当前最字符串。比如可以将min_str设为一个很长的字符串或者Infinity。 2. 遍历字符串字典中的每个字符串,可以使用循环来实现。假设字符串字典存储在一个数组str_list中。 3. 在循环中,对于每个字符串str,比较其长度与min_str的长度。如果str的长度更小,则更新min_str为当前的str。 4. 循环结束后,min_str即为最字符串。 该算法的时间复杂度为O(n),其中n为字符串字典中的字符串数量。因为我们需要遍历整个字符串字典一次来找到最字符串。 不过需要注意的是,这个算法假设了字符串字典中的每个字符串都是有效的,且最字符串只有一个。如果字符串字典中存在无效字符串,或者最字符串不只一个,该算法可能会出现错误结果。 如果字符串字典中存在大量字符串,或者需要频繁查找最字符串,可以考虑使用更高效的数据结构,例如二叉堆或者平衡二叉搜索树,来实现更优化的算法。 ### 回答3: 最字符串的算法分析如下: 问题描述:给定一个字符串数组,要求从中找出最字符串。 解题思路: 1. 初始化一个变量min_length,用于记录最字符串的长度,初始值可以设为正无穷大。 2. 遍历字符串数组中的每一个字符串,设当前遍历到的字符串为s。 3. 判断当前字符串s的长度是否小于min_length,如果是,则更新min_length的值为s的长度。 4. 继续遍历下一个字符串。 5. 最后返回长度为min_length的字符串即可。 算法复杂度分析: - 时间复杂度:该算法需要遍历字符串数组中的每一个字符串,时间复杂度为O(n),其中n为字符串数组的长度。 - 空间复杂度:该算法只需要常数级别的额外空间,空间复杂度为O(1)。 代码示例(Python): ``` def find_shortest_string(strings): min_length = float('inf') shortest_string = "" for s in strings: if len(s) < min_length: # 判断当前字符串的长度是否小于min_length min_length = len(s) # 更新min_length的值 shortest_string = s # 更新最字符串 return shortest_string # 测试 strings = ["apple", "banana", "cat", "dog", "elephant"] shortest_string = find_shortest_string(strings) print("最字符串是:", shortest_string) ``` 输出结果为:"最字符串是: cat"。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不过是条河鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值