题目
给你一个字符串
s
、一个字符串t
。返回s
中涵盖t
所有字符的最小子串。如果s
中不存在涵盖t
所有字符的子串,则返回空字符串""
注意:
- 对于
t
中重复字符,我们寻找的子字符串中该字符数量必须不少于t
中该字符数量。- 如果
s
中存在这样的子串,我们保证它是唯一的答案。
分析
包含所有t的最小字符串
字符串 => s.slice
最小=》 滑动窗口 + left 到达条件后 left++
解法:滑动窗口
思路
1. 因为Map会超时,所以才去字典的方式来优化时间
2. 先扩大滑动窗口直到满足条件
3. 再根据满足的情况缩进左边的的窗口 来求得最小的滑动窗口大小
*/
// @lc code=start
/**
* @param {string} s
* @param {string} t
* @return {string}
*/
var minWindow = function (s, t) {
// 因为包含大小写英文 所以字典的最大取值范围是 'z'.charCodeAt()-'A'.charCodeAt()
const sArr = new Array('z'.charCodeAt()-'A'.charCodeAt()+1).fill(0);
const tArr = new Array('z'.charCodeAt()-'A'.charCodeAt()+1).fill(0);
let minStr = "";
let min = Infinity;
const AChar = "A".charCodeAt();
if (s.length < t.length) return minStr;
// 建立t的字典 记录t中字母出现的次数
for (let i = 0; i < t.length; i++) {
tArr[t[i].charCodeAt() - AChar]++;
}
// 左边的指针
let j = 0;
for (let i = 0; i < s.length; i++) {
// 满足t字典的才放入s字典中
if (tArr[s[i].charCodeAt() - AChar]) {
sArr[s[i].charCodeAt() - AChar]++;
}
// 当满足条件时候 在不断缩小左指针 来求得最小的窗口大小
while (matchCondition() && j <= i) {
if (i - j + 1 < min) {
min = i - j + 1;
minStr = s.slice(j, i + 1);
}
if (tArr[s[j].charCodeAt() - AChar]) {
sArr[s[j].charCodeAt() - AChar]--;
}
j++;
}
}
// 判断是否满足条件
function matchCondition() {
for (let i = 0; i < sArr.length; i++) {
if (sArr[i] < tArr[i]) return false;
}
return true;
}
return minStr;
};
//时间复杂度:O(n*m) n 为s的长度 m为t字典集的大小
//空间复杂度:O(m)
总结
今天这道题是主要是练习如何使用不固定尺寸的滑动窗口 来求连续子串类最小长度的题目
大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢
大家如果对“TS”感兴趣的可以看看我的专栏 (TypeScript常用知识),感谢大家的支持
文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com
\