写点什么

滑动窗口算法

作者:方勇(gopher)
  • 2022 年 3 月 31 日
  • 本文字数:944 字

    阅读完需:约 3 分钟

滑动窗口算法

76. 最小覆盖子串

难度困难 1758 收藏分享切换为英文接收动态反馈

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

 

注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。

  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。

 

示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"输出:"BANC"
复制代码

示例 2:

输入:s = "a", t = "a"输出:"a"
复制代码

示例 3:

输入: s = "a", t = "aa"输出: ""解释: t 中两个字符 'a' 均应包含在 s 的子串中,因此没有符合条件的子字符串,返回空字符串。
复制代码

 

提示:

  • 1 <= s.length, t.length <= 105

  • s 和 t 由英文字母组成

 

进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?

题解:

func minWindow(s string, t string) string {	var solution func(s, t string) string // 解决方案	solution = func(s, t string) string {		var window = map[string]int{} // 滑动窗口		var need = map[string]int{}   // 目标态		var valid, left, right, start int		var step = math.MaxInt // 初始化最大步长		for _, v := range t {			need[string(v)]++ // 初始化目标态		}		length := len(s)		for right < length { // 开始求解			c := string(s[right]) // 取出要判断的字符			right++               // 右移窗口
if _, ok := need[c]; ok { // 命中目标态 window[c]++ // 放入窗口 if window[c] == need[c] { valid++ // 该字符已达到目标态 } }
for valid == len(need) { // 全部完成目标态 if right-left < step { // 缩小窗口 start = left // 最终返回字符的左边界 step = right - left // 窗口大小 }
d := string(s[left]) left++ // 缩小窗口 if _, ok := need[d]; ok { if window[d] == need[d] { valid-- // 不满足目标态了 } window[d]-- // 从窗口中减去数据 }
} } if step < math.MaxInt { //找到结果 return s[start : start+step] // Golang语言特性 [左区间, 左区间+步长] }
return "" // 未找到 }
return solution(s, t)}
复制代码


用户头像

Dead or Alive. 生存战斗是知识的源泉! 2018.11.08 加入

我是一名SRE哨兵,目前是好大夫基础架构部高级工程师。专注于 SRE,微服务、中间件的稳定性和可用性建设,整体负责好大夫服务治理云平台的设计和搭建!

评论

发布
暂无评论
滑动窗口算法_LeetCode_方勇(gopher)_InfoQ写作平台