定义
滑动窗口只是形象的表述,其本质应该算是一种双指针。
两个指针对应窗口的左右边界,一般情况右指针先走,当窗口大小不满足或者一些条件不满足时,左指针移动,使窗口内元素满足题目条件。
不使用双指针,也可以使用多层for循环的形式,使用双指针,时间复杂度变成o(n),相当于使用脑力换时间。
适用范围
- 1、一般是字符串或者数组
-
算法思想
1、在序列中使用双指针中的左右指针技巧,初始化 left = right = 0,把索引闭区间 [left, right] 称为一个窗口。
2、先不断地增加 right 指针扩大窗口 [left, right],直到窗口中的序列符合要求。
3、此时,停止增加 right,转而不断增加 left 指针缩小窗口 [left, right],直到窗口中的序列不再符合要求。同时,每次增加 left前,都要更新一轮结果。
4、重复第 2 和第 3 步,直到 right 到达序列的尽头。算法模板
单层循环
def template():# 初始化滑动窗口两端left = right = 0# 序列及序列长度seq, seq_len = xx, xx# 滑动窗口序列slide_win = []# 结果值rst = xxwhile right < seq_len:slide_win.append(seq[right])# 还没找到一个可行解if not avaliable(slide_win):# 扩大窗口right += 1else:# 找到一个可行解,更新结果值rst = update()# 缩小窗口left += 1
多层循环
def template():# 初始化滑动窗口两端left = right = 0# 序列及序列长度seq, seq_len = xx, xx# 滑动窗口序列slide_win = []# 结果值rst = xxwhile right < seq_len:slide_win.append(seq[right])# 还没找到一个可行解if not avaliable(slide_win):# 扩大窗口right += 1continue# 循环更新可行解while avaliable(slide_win):# 找到一个可行解,更新结果值rst = update()# 缩小窗口left += 1
leetcode
15:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。var threeSum = function(nums) {let res = [], len = nums.length, left, rightif (len < 3) return resnums = nums.sort((a, b) => a - b)for (let i = 0; i < len; i++) {if (nums[i] > 0) breakif (i > 0 && nums[i] === nums[i - 1]) continueleft = i + 1right = len - 1while (left < right) {let sum = nums[i] + nums[left] + nums[right]if (sum === 0) {res.push([nums[i], nums[left], nums[right]])while (left < right && nums[left] === nums[left + 1]) left++while (left < right && nums[right] === nums[right - 1]) right--left++right--} else if (sum > 0) {right--} else if (sum < 0) {left++}}}return res};
