力扣76. 最小覆盖子串
Posted super码王
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣76. 最小覆盖子串相关的知识,希望对你有一定的参考价值。
题目
给你一个字符串 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 的子串中,
因此没有符合条件的子字符串,返回空字符串。
思路分析
- 存储 目标字符串
t 中出现的字符及次数 [omap]
定义左右双指正[left,right],右指针遍历源字符串s
遍历 源字符串s ,如果这个字符在
目标字符串t中出现过,则存储 [cmap]
比对omap和cmap,如果相等 且 子字符串长度 小于minlen则将这个左右位置存储下来,移动左指正
- 最后返回目标子字符串
代码实现
/**
* @param string s
* @param string t
* @return string
*/
var minWindow = function (s, t)
// omap 存储 t 里面每个字符出现的次数
let omap = new Map()
for (let i in t)
if (omap.get(t[i]) === undefined)
omap.set(t[i], 1)
else
omap.set(t[i], omap.get(t[i]) + 1)
// cmap 存储 s 里面出现的 在 t 里面存在的字符
let cmap = new Map()
let right = 0
let left = 0
let mLeft = 0
let mRight = 0
let minLen = 99999
for (; right < s.length; right++)
if (omap.get(s[right]) != undefined)
if (cmap.get(s[right]) === undefined)
cmap.set(s[right], 1)
else
cmap.set(s[right], cmap.get(s[right]) + 1)
while (checked(omap, cmap))
let tempLen = right - left + 1
//只有当这个长度比 原来设定的短,才走这一步
if (tempLen < minLen)
mLeft = left
mRight = right
minLen = tempLen
if (cmap.get(s[left]) != undefined)
cmap.set(s[left], cmap.get(s[left]) - 1)
left++
return minLen === 99999 ? "" : s.substring(mLeft, mRight + 1)
let checked = (o, c) =>
let flag = true
o.forEach((val, key) =>
if (c.get(key) === undefined || c.get(key) < val)
flag = false
)
return flag
运行结果
以上是关于力扣76. 最小覆盖子串的主要内容,如果未能解决你的问题,请参考以下文章