239. 滑动窗口最大值

思路与代码实现
利用双端队列, 在其头部存储当前窗口的最大值的索引
向右滑动窗口, 从尾部入队列的元素从尾部向前依次比较, 从尾部弹出比其小的元素, 再将其从尾部入队
如果双端队列的头部元素超出窗口的宽度, 则从头部删除该元素
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var maxSlidingWindow = function(nums, k) {
// 考虑边界情况
if (nums.length < k || nums.length === 0) {
return nums
} else {
const numsLength = nums.length
const answer = []
const slidingWindow = []
// 初始化第一个窗口
for (let i = 0; i < k; ++i) {
while (slidingWindow.length > 0 && nums[i] > nums[slidingWindow[slidingWindow.length - 1]]) {
slidingWindow.pop()
}
slidingWindow.push(i)
}
answer.push(nums[slidingWindow[0]])
// 遍历数组
for (let i = k; i < numsLength; ++i) {
// 删除超出窗口左侧的数组下标
let start = 0
while (slidingWindow[start] < i - k + 1) {
++start
}
slidingWindow.splice(0, start)
// 删除小于当前元素值的数组下标
while (slidingWindow.length > 0 && nums[i] > nums[slidingWindow[slidingWindow.length - 1]]) {
slidingWindow.pop()
}
slidingWindow.push(i)
answer.push(nums[slidingWindow[0]])
}
return answer
}
}
76. 最小覆盖子串

思路与代码实现
向右移动右指针, 直至符合条件, 再向右移动左指针, 直至不符合条件
/**
* @param {string} s
* @param {string} t
* @return {string}
*/
var minWindow = function(s, t) {
if (s.length < t.length) {
return ''
} else {
let leftPointer = 0
let rightPointer = 0
let res = s
let existFlag = false
const targetHashTable = {}
const windowHashTable = {}
// 生成目标哈希表
for (let i = t.length - 1; i >= 0; i--) {
if (targetHashTable[t[i]] === undefined) {
targetHashTable[t[i]] = 1
} else {
targetHashTable[t[i]]++
}
}
// 是否符合要求
function isFit (windowHashTable, targetHashTable) {
for (let str in targetHashTable) {
if (windowHashTable[str] === undefined) {
return false
} else {
if (windowHashTable[str] < targetHashTable[str]) {
return false
}
}
}
existFlag = true
return true
}
while (rightPointer < s.length) {
// 向右移动右指针, 并在窗口哈希表记录每个字符出现的次数
const currentStr = s[rightPointer]
if (windowHashTable[currentStr] === undefined) {
windowHashTable[currentStr] = 1
} else {
windowHashTable[currentStr]++
}
rightPointer++
// 向右移动左指针, 缩小窗口, 直至不符合要求
while (isFit(windowHashTable, targetHashTable)) {
// 更新结果
const _res = s.substring(leftPointer, rightPointer)
if (_res.length < res.length) {
res = _res
}
const currentStr = s[leftPointer]
windowHashTable[currentStr]--
leftPointer++
}
}
return existFlag ? res : ''
}
};
209. 长度最小的子数组

思路与代码实现
同上, 向右移动右指针, 直至符合条件, 再向右移动左指针, 直至不符合条件
/**
* @param {number} s
* @param {number[]} nums
* @return {number}
*/
var minSubArrayLen = function (s, nums) {
let sum = 0
let leftPointer = 0
let rightPointer = 0
let res = nums.length
let flag = false
while (rightPointer < nums.length && sum < s) {
// 向右移动右指针, 增加窗口宽度
sum += nums[rightPointer]
rightPointer++
// 向右移动左指针, 减小窗口宽度
while (sum >= s) {
if (sum >= s && rightPointer - leftPointer <= res) {
flag = true
res = rightPointer - leftPointer
}
sum -= nums[leftPointer]
leftPointer++
}
}
return flag ? res : 0
};