From ed905ac3a324b3a8a4b2858585b03b8bf64979cc Mon Sep 17 00:00:00 2001 From: watch <707491663@qq.com> Date: Mon, 20 Apr 2020 09:39:23 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=BB=91=E5=8A=A8=E7=AA=97=E5=8F=A3?= =?UTF-8?q?=E7=AC=AC=E4=B8=80=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SlidingWindow/01-introduction.md | 5 ++ SlidingWindow/02-type-1.md | 81 ++++++++++++++++++ SlidingWindow/03-type-2.md | 46 ++++++++++ SlidingWindow/04-type-3.md | 42 +++++++++ SlidingWindow/05-summary.md | 3 + SlidingWindow/06-practices.md | 8 ++ .../\347\244\272\346\204\217\345\233\276.jpg" | Bin 0 -> 24396 bytes _sidebar.md | 19 ++-- 8 files changed, 198 insertions(+), 6 deletions(-) create mode 100644 SlidingWindow/01-introduction.md create mode 100644 SlidingWindow/02-type-1.md create mode 100644 SlidingWindow/03-type-2.md create mode 100644 SlidingWindow/04-type-3.md create mode 100644 SlidingWindow/05-summary.md create mode 100644 SlidingWindow/06-practices.md create mode 100644 "SlidingWindow/\347\244\272\346\204\217\345\233\276.jpg" diff --git a/SlidingWindow/01-introduction.md b/SlidingWindow/01-introduction.md new file mode 100644 index 0000000..164ec75 --- /dev/null +++ b/SlidingWindow/01-introduction.md @@ -0,0 +1,5 @@ +# 滑动窗口 + +滑动窗口思想常用于处理数组、字符串相关的问题,它使用两个指针,指针间表示为一个窗口,这个窗口不停地滑动,每次都记录窗口的当前状态,再找出符合条件的适合的窗口,以求得解。 + +示意图 \ No newline at end of file diff --git a/SlidingWindow/02-type-1.md b/SlidingWindow/02-type-1.md new file mode 100644 index 0000000..f980d35 --- /dev/null +++ b/SlidingWindow/02-type-1.md @@ -0,0 +1,81 @@ +## 类型 1:窗口大小随指针移动而改变(常见) + +例题:「LeetCode」 第 209 题:[长度最小的子数组](https://leetcode-cn.com/problems/minimum-size-subarray-sum/) + +> 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。 +> +> 示例: +> +> 输入: s = 7, nums = [2,3,1,2,4,3] +> 输出: 2 +> 解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。 + +**面对一个问题,如果我们一时想不到好的解法,可以先从暴力解入手。本题暴力解思路如下**: + +* 遍历由索引 i 到索引 j 的所有的连续子数组 `nums[i...j]` + +* 计算子数组的和 sum,验证 `sum >= s` + +* 对于所有满足条件的解,找出长度最小的解 + + +可以看出,因为子数组的长度可以由 n 到 1,所以本解法的时间复杂度为:O (n^3) + +#### 暴力解的问题 + +我们可以很快发现,如果我们可以知道 `nums[i...j] `的值,那 `nums[i...j-1]` 的值是不是早已被计算过了呢?因此,**暴力解的最大问题,就是存在大量重复的运算** + +#### 使用滑动窗口,避免重复运算 + +为了使每次计算都有意义,我们可以定义一个左指针 `lp` ,一个右指针 `rp` ,而 `nums[lp...rp]` 就是一个「窗口」。应用窗口的思路如下: + +* 若窗口间的元素之和小于 s ,即 `sum(nums[lp...rp]) < s` ,则让右指针滑动一位,即 `rp+1` ,使得窗口间元素之和变大; +* 若窗口间的元素之和大于等于于 s ,即 `sum(nums[lp...rp]) >= s` ,我们记录此时窗口的长度,并让左指针滑动一位,即 `lp+1` ,使得窗口间元素之和变小,若此时的窗口仍满足条件,则再记录窗口的长度,直到窗口不满足条件; +* 返回记录的窗口中,最小的窗口长度 + +python 代码: + +```python +class Solution: + def minSubArrayLen(self, s: int, nums) -> int: + lp = 0 # 左指针 + rp = 0 # 右指针 + table = [] # 存放所有满足条件的子数组长度 + total = 0 # 记录满足条件的窗口长度 + nlen = len(nums) + + while rp < nlen: + total += nums[rp] + while total >= s: # 当窗口满足条件时,不断移动左指针,直到窗口不满足条件 + table.append(rp - lp + 1) + total -= nums[lp] + lp += 1 + rp += 1 + + return min(table) if table else 0 # 如果找不到满足条件的窗口,返回0 +``` + +我们可以发现,最后需要返回的其实只有一个值,并不需要记录所有满足条件的窗口长度,因此代码在空间上可以优化,代码如下: + +```python +class Solution: + def minSubArrayLen(self, s: int, nums) -> int: + nlen = len(nums) + res = nlen+1 # 将最小长度初始化为一个不可能的值 + lp = 0 + rp = 0 + total = 0 # 记录数组之和 + while rp < nlen: + total += nums[rp] + while total >= s: + res = min(res, rp-lp+1) # 始终存储最小的长度 + total -= nums[lp] + lp += 1 + rp += 1 + + return res if res < nlen+1 else 0 +``` + +**注意:** + +* 对于窗口,我们必须明确左右指针的具体含义,即指针指向的元素属不属于这个窗口。在本题中,我们定义的是 `[lp...rp]` 左闭右闭的窗口,即左指针与右指针指向的元素都属于窗口,各位也可以尝试定义 `[lp...rp)` 或 `(lp...rp]` 的窗口 diff --git a/SlidingWindow/03-type-2.md b/SlidingWindow/03-type-2.md new file mode 100644 index 0000000..d5c323f --- /dev/null +++ b/SlidingWindow/03-type-2.md @@ -0,0 +1,46 @@ +## 类型 2:窗口大小不随指针移动而改变 + +例题:「LeetCode」 第 219 题:[存在重复元素 II](https://leetcode-cn.com/problems/contains-duplicate-ii/) + +> 给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k。 +> +> 示例 1: +> +> 输入: nums = [1,2,3,1], k = 3 +> 输出: true +> +> 示例 2: +> +> 输入: nums = [1,2,3,1,2,3], k = 2 +> 输出: false + +#### 思路 + +这道题乍一看好像和滑动窗口没关系,但我们可以发现这是一个数组问题,需要频繁地使用索引(指针),而且有成立条件。因此我们可以将题目转换一下,变为: + +* 给定一个整数数组和大小为 k 的窗口,判断窗口中是否能存在重复元素。 + +这样一来,本题就变成了一个窗口大小不变的滑动窗口问题,思路也不难想了: + +* 定义一个长度最大为 k 的窗口; +* 若某元素不在窗口中,则将此元素加入窗口;若此时窗口超过了最大长度,则将先加进来的元素移出窗口; +* 若某元素已在窗口中,返回 True ;若遍历整个数组后,窗口中仍没有重复元素,返回 False + +python 代码: + +```python +class Solution: + def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool: + window = set() # 使用一个集合表示窗口 + + for i in range(len(nums)): + if nums[i] in window: + return True + + window.add(nums[i]) + + if len(window) > k: + window.remove(nums[i-k]) # 移出最先加进来的元素 + + return False +``` \ No newline at end of file diff --git a/SlidingWindow/04-type-3.md b/SlidingWindow/04-type-3.md new file mode 100644 index 0000000..d007635 --- /dev/null +++ b/SlidingWindow/04-type-3.md @@ -0,0 +1,42 @@ +## 类型3:使用对撞指针的滑动窗口 + +「对撞指针」是双指针的一种变形,一个指针指向数组头,一个指向数组尾,两指针往相反的方向移动。而指针间可以被认为是一个窗口,这类滑动窗口也常常带有一点贪心算法的思想,例题如下: + +「LeetCode」 第 11 题:[盛最多水的容器](https://leetcode-cn.com/problems/container-with-most-water/) + +> 给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 +> +> 示例: +> +> 输入:[1,8,6,2,5,4,8,3,7] +> 输出:49 + +假设给定的数组为 `height` ,则示例中的输出则可解释为 `49 = min(height[1], height[8]) * (8-1)` + +#### 思路 + +根据「木桶原理」,我们知道决定一个容器能盛多少水的因素有两个,一个是容器本身有多大,二是最短的那块木板有多长。而在这道题,数组中的元素值代表木板长度,两元素间的间距代表容器本身的大小,即窗口的大小。 + +可以发现,我们虽然不知道木板最长是多少,但窗口可以有多大是知道的——即数组长度 - 1那么大。因此我们不妨在一开始就把窗口设为最大,每次判断当前木板的长度和窗口大小能盛多少水,再逐渐将窗口缩小。至此,代码也就呼之欲出了。 + +python代码: + +```python +class Solution: + def maxArea(self, height: List[int]) -> int: + lp = 0 # 左指针,指向左侧的木板 + rp = len(height) - 1 # 右指针,指向右侧的木板 + res = 0 # 能容纳的最大水量 + + while lp < rp: + # 每次计算当前窗口和木板长度能容纳的水量,并更新能容纳的最大水量 + temp = min(height[lp], height[rp]) * (rp-lp) + res = max(res, temp) + # 不断更换长度相对短的那个木板 + if height[lp] < height[rp]: + lp += 1 + else: + rp -= 1 + + return res +``` \ No newline at end of file diff --git a/SlidingWindow/05-summary.md b/SlidingWindow/05-summary.md new file mode 100644 index 0000000..c9dad73 --- /dev/null +++ b/SlidingWindow/05-summary.md @@ -0,0 +1,3 @@ +## 总结 + +其实滑动窗口问题还是以类型 1 居多,重点在于思考左右指针的具体含义、窗口状态的具体含义,以及窗口要如何变化,变化条件又是什么。明白了这些,也就彻底理解了滑动窗口。 diff --git a/SlidingWindow/06-practices.md b/SlidingWindow/06-practices.md new file mode 100644 index 0000000..2c50498 --- /dev/null +++ b/SlidingWindow/06-practices.md @@ -0,0 +1,8 @@ +## 精选例题 + +| 题目 | 提示 | +| :----------------------------------------------------------: | :--------------------------------------: | +| [3.无重复字符的最长子串](https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/) | 非常经典的一道滑动窗口问题,建议反复理解 | +| [438. 找到字符串中所有字母异位词](https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/) | 「无重复字符的最长子串」的变形 | +| [76. 最小覆盖子串](https://leetcode-cn.com/problems/minimum-window-substring/) | 「无重复字符的最长子串」的进阶,相对较难 | + diff --git "a/SlidingWindow/\347\244\272\346\204\217\345\233\276.jpg" "b/SlidingWindow/\347\244\272\346\204\217\345\233\276.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..232f895d161daa514f4bc99d01392c7eec0c8e7d GIT binary patch literal 24396 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 literal 0 HcmV?d00001 diff --git a/_sidebar.md b/_sidebar.md index 4def75e..cb57f52 100644 --- a/_sidebar.md +++ b/_sidebar.md @@ -1,7 +1,14 @@ - 二分查找 - - [简介](/BinarySearch/01-introduction.md) - - [模板一](/BinarySearch/02-template-1.md) - - [模板二](/BinarySearch/03-template-2.md) - - [模板三](/BinarySearch/04-template-3.md) - - [例题](/BinarySearch/05-examples.md) - - [练习](/BinarySearch/06-practices.md) + - [简介](./BinarySearch/01-introduction.md) + - [模板一](./BinarySearch/02-template-1.md) + - [模板二](./BinarySearch/03-template-2.md) + - [模板三](./BinarySearch/04-template-3.md) + - [例题](./BinarySearch/05-examples.md) + - [练习](./BinarySearch/06-practices.md) +- 滑动窗口 + - [简介](./SlidingWindow/01-introduction.md) + - [类型一](./SlidingWindow/02-type-1.md) + - [类型二](./SlidingWindow/03-type-2.md) + - [类型三](./SlidingWindow/04-type-3.md) + - [总结](./SlidingWindow/05-summary.md) + - [练习题](./SlidingWindow/06-practices.md) From fe52e260363e9d7c72a02eac75fe7ac32d5cb88b Mon Sep 17 00:00:00 2001 From: starwingchen <44251923+starwingChen@users.noreply.github.com> Date: Mon, 20 Apr 2020 09:43:33 +0800 Subject: [PATCH 2/4] Update 02-type-1.md --- SlidingWindow/02-type-1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SlidingWindow/02-type-1.md b/SlidingWindow/02-type-1.md index f980d35..33178e3 100644 --- a/SlidingWindow/02-type-1.md +++ b/SlidingWindow/02-type-1.md @@ -21,11 +21,11 @@ 可以看出,因为子数组的长度可以由 n 到 1,所以本解法的时间复杂度为:O (n^3) -#### 暴力解的问题 +### 暴力解的问题 我们可以很快发现,如果我们可以知道 `nums[i...j] `的值,那 `nums[i...j-1]` 的值是不是早已被计算过了呢?因此,**暴力解的最大问题,就是存在大量重复的运算** -#### 使用滑动窗口,避免重复运算 +### 使用滑动窗口,避免重复运算 为了使每次计算都有意义,我们可以定义一个左指针 `lp` ,一个右指针 `rp` ,而 `nums[lp...rp]` 就是一个「窗口」。应用窗口的思路如下: From 220d4a7bf2a86ea515f0b5c84b03a58100f70874 Mon Sep 17 00:00:00 2001 From: starwingchen <44251923+starwingChen@users.noreply.github.com> Date: Mon, 20 Apr 2020 09:44:53 +0800 Subject: [PATCH 3/4] Update 04-type-3.md --- SlidingWindow/04-type-3.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SlidingWindow/04-type-3.md b/SlidingWindow/04-type-3.md index d007635..4728024 100644 --- a/SlidingWindow/04-type-3.md +++ b/SlidingWindow/04-type-3.md @@ -13,7 +13,7 @@ 假设给定的数组为 `height` ,则示例中的输出则可解释为 `49 = min(height[1], height[8]) * (8-1)` -#### 思路 +### 思路 根据「木桶原理」,我们知道决定一个容器能盛多少水的因素有两个,一个是容器本身有多大,二是最短的那块木板有多长。而在这道题,数组中的元素值代表木板长度,两元素间的间距代表容器本身的大小,即窗口的大小。 @@ -39,4 +39,4 @@ class Solution: rp -= 1 return res -``` \ No newline at end of file +``` From aba6aa323ab0b2629ad9b123b20ed0003430d04d Mon Sep 17 00:00:00 2001 From: starwingchen <44251923+starwingChen@users.noreply.github.com> Date: Mon, 20 Apr 2020 09:45:06 +0800 Subject: [PATCH 4/4] Update 03-type-2.md --- SlidingWindow/03-type-2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SlidingWindow/03-type-2.md b/SlidingWindow/03-type-2.md index d5c323f..afe0d80 100644 --- a/SlidingWindow/03-type-2.md +++ b/SlidingWindow/03-type-2.md @@ -14,7 +14,7 @@ > 输入: nums = [1,2,3,1,2,3], k = 2 > 输出: false -#### 思路 +### 思路 这道题乍一看好像和滑动窗口没关系,但我们可以发现这是一个数组问题,需要频繁地使用索引(指针),而且有成立条件。因此我们可以将题目转换一下,变为: @@ -43,4 +43,4 @@ class Solution: window.remove(nums[i-k]) # 移出最先加进来的元素 return False -``` \ No newline at end of file +```