📜  门| GATE-CS-2007 |第 58 题(1)

📅  最后修改于: 2023-12-03 14:58:27.562000             🧑  作者: Mango

题目描述

在一个字符串中找到一个最小子串,使得这个子串中包含了指定的所有字符。

函数签名
def find_shortest_substring(s: str, chars: str) -> str:
  pass
输入
  • s:一个字符串。
  • chars:一个字符串,其中包含指定的字符。
输出

一个字符串,表示chars中包含的所有字符的最短子串。

示例
assert find_shortest_substring('this is a test string', 'tist') == 't stri'
分析
  • 这道题需要使用一个滑动窗口和一个字典。
  • 首先将chars中每个字符加入到字典中,并初始化滑动窗口的左、右边界。
  • 移动右边界,直到字典中的所有字符都在滑动窗口中。
  • 接着移动左边界,直到滑动窗口中的所有字符不再是指定的字符。
  • 此时,更新最短子串的长度和位置。
  • 重复以上步骤,直到遍历完整个字符串。
代码实现
def find_shortest_substring(s: str, chars: str) -> str:
    char_map = {}
    for c in chars:
        char_map[c] = char_map.get(c, 0) + 1

    left, right = 0, 0
    min_length = float('inf')
    min_start = 0
    count = len(char_map)

    while right < len(s):
        c = s[right]
        if c in char_map:
            char_map[c] -= 1
            if char_map[c] == 0:
                count -= 1
        right += 1

        while count == 0:
            if right - left < min_length:
                min_length = right - left
                min_start = left

            c = s[left]
            if c in char_map:
                char_map[c] += 1
                if char_map[c] > 0:
                    count += 1
            left += 1

    return s[min_start:min_start+min_length] if min_length != float('inf') else ''

时间复杂度:$O(S+C)$,其中 S 是字符串的长度,C 是字符集的大小。在最坏情况下,我们需要遍历整个字符串 s 以及字符集 chars 中的所有字符。

空间复杂度:$O(C)$,字典存储了字符集 chars