题目

解答
想到使用双指针+哈希表来实现,双指针的left和right控制实现可满足字符串。
class Solution(object):def minWindow(self, s, t):""":type s: str:type t: str:rtype: str"""len_s, len_t = len(s), len(t)hash_map = {}for i in range(len_t):if t[i] in hash_map:hash_map[t[i]] += 1else:hash_map.setdefault(t[i], 1)copy_hash = deepcopy(hash_map)min_len = 1e5min_left = 0tag = False # 记录是否已经找到满足条件子串for left in range(len_s):if s[left] not in hash_map:continueright = leftwhile len(copy_hash) != 0 and right < len_s:if s[right] in copy_hash:if copy_hash[s[right]] > 1:copy_hash[s[right]] -= 1elif copy_hash[s[right]] == 1:copy_hash.pop(s[right])right += 1if len(copy_hash) != 0: #代表right >= len_sbreakelse: # 代表找到一个合法块满足要求tag = Truecurrent_len = right - leftif current_len < min_len:min_len = current_lenmin_left = leftcopy_hash = deepcopy(hash_map)if tag == True:return s[int(min_left):int(min_left+min_len)]else:return ""
报错:
仔细看了代码,发现我使用的双指针会造成平方复杂度,每次左指针移动后,都重新从当前的left位置开始扩展右指针,这样会有大量的重复计算。所以,需要重新设计算法,使用更高效的滑动窗口方法。可能的改进方向是:维护一个滑动窗口,用两个指针left和right。先扩展right直到窗口包含所有t的字符,然后尝试移动left缩小窗口,同时更新最小窗口的长度。这样每个元素最多被访问两次(left和right各一次),时间复杂度为O(n)。另外,原来的代码中使用了deepcopy来恢复copy_hash,这可能也很耗时。因为每次循环都要复制整个哈希表,当哈希表较大时,这会增加时间消耗。应该维护一个当前的计数器,动态地增减字符出现的次数,而不是每次都复制哈希表。
修改后的代码如下:
class Solution(object):def minWindow(self, s, t):""":type s: str:type t: str:rtype: str"""# 构造哈希表-tmap_t = defaultdict(int)for st in t:map_t[st] += 1# 需要符合条件的字符数require_len = len(map_t)current_window = defaultdict(int)try_len = 0left = 0min_len = 1e5min_left = 0tag = Falsefor right in range(len(s)):current_window[s[right]] += 1if s[right] in map_t and current_window[s[right]] == map_t[s[right]]:try_len += 1while try_len == require_len and left <= right:tag = Truecurrent_len = right - left + 1if current_len < min_len:min_len = current_lenmin_left = leftcurrent_window[s[left]] -= 1if s[left] in map_t and current_window[s[left]] < map_t[s[left]]:try_len -= 1left += 1if tag == True:return s[min_left: min_left + min_len]else:return ""