66
77## 2. 对撞指针  
88
9- >  ** 对撞指针** :指的是两个指针 ` left ` 、` right `  分别指向序列第一个元素和最后一个元素,然后 ` left `  指针不断递增,` right `  不断递减,直到两个指针的值相撞(即 ` left == right ` ),或者满足其他要求的特殊条件为止。
9+ >  ** 对撞指针** :指的是两个指针 $left$、$right$ 分别指向序列第一个元素和最后一个元素,然后 $left$ 指针不断递增,$right$ 不断递减,直到两个指针的值相撞(即 $left == right$),或者满足其他要求的特殊条件为止。
10+ 
11+ ![ 对撞指针] ( https://qcdn.itcharge.cn/images/20230906165407.png ) 
1012
1113### 2.1 对撞指针求解步骤  
1214
13- 1 .  使用两个指针 ` left ` , ` right ` 。 ` left `  指向序列第一个元素,即:` left = 0 ` , ` right `  指向序列最后一个元素,即:` right = len(nums) - 1 ` 。
14- 2 .  在循环体中将左右指针相向移动,当满足一定条件时,将左指针右移,` left += 1 ` 。当满足另外一定条件时,将右指针左移,` right -= 1 ` 。
15- 3 .  直到两指针相撞(即 ` left == right ` ),或者满足其他要求的特殊条件时,跳出循环体。
15+ 1 .  使用两个指针 $ left$,$ right$。$ left$  指向序列第一个元素,即:$ left = 0$,$ right$  指向序列最后一个元素,即:$ right = len(nums) - 1$ 。
16+ 2 .  在循环体中将左右指针相向移动,当满足一定条件时,将左指针右移,$ left += 1$ 。当满足另外一定条件时,将右指针左移,$ right -= 1$ 。
17+ 3 .  直到两指针相撞(即 $ left == right$ ),或者满足其他要求的特殊条件时,跳出循环体。
1618
1719### 2.2 对撞指针伪代码模板  
1820
@@ -47,9 +49,9 @@ return 没找到 或 找到对应值
4749
4850#### 2.4.2 题目大意  
4951
50- ** 描述** :给定一个下标从 ` 1 `  开始计数、升序排列的整数数组:` numbers `  和一个目标值 ` target ` 。
52+ ** 描述** :给定一个下标从 $1$  开始计数、升序排列的整数数组:$ numbers$  和一个目标值 $ target$ 。
5153
52- ** 要求** :从数组中找出满足相加之和等于 ` target `  的两个数,并返回两个数在数组中下的标值。
54+ ** 要求** :从数组中找出满足相加之和等于 $ target$  的两个数,并返回两个数在数组中下的标值。
5355
5456** 说明** :
5557
@@ -61,20 +63,25 @@ return 没找到 或 找到对应值
6163
6264** 示例** :
6365
66+ -  示例 1:
67+ 
6468``` python 
6569输入:numbers =  [2 ,7 ,11 ,15 ], target =  9 
6670输出:[1 ,2 ]
6771解释:2  与 7  之和等于目标数 9  。因此 index1 =  1 , index2 =  2  。返回 [1 , 2 ] 。
72+ ``` 
6873
74+ -  示例 2:
6975
76+ ``` python 
7077输入:numbers =  [2 ,3 ,4 ], target =  6 
7178输出:[1 ,3 ]
7279解释:2  与 4  之和等于目标数 6  。因此 index1 =  1 , index2 =  3  。返回 [1 , 3 ] 。
7380``` 
7481
7582#### 2.4.3 解题思路  
7683
77- 这道题如果暴力遍历数组,从中找到相加之和等于 ` target `  的两个数,时间复杂度为 $O(n^2)$,可以尝试一下。
84+ 这道题如果暴力遍历数组,从中找到相加之和等于 $ target$  的两个数,时间复杂度为 $O(n^2)$,可以尝试一下。
7885
7986``` python 
8087class  Solution :
@@ -93,13 +100,13 @@ class Solution:
93100
94101可以考虑使用对撞指针来减少时间复杂度。具体做法如下:
95102
96- 1 .  使用两个指针 ` left ` , ` right ` 。 ` left `  指向数组第一个值最小的元素位置,` right `  指向数组值最大元素位置。
103+ 1 .  使用两个指针 $ left$,$ right$。$ left$  指向数组第一个值最小的元素位置,$ right$  指向数组值最大元素位置。
971042 .  判断两个位置上的元素的和与目标值的关系。
98105   1 .  如果元素和等于目标值,则返回两个元素位置。
99-    2 .  如果元素和大于目标值,则让 ` right `  左移,继续检测。
100-    3 .  如果元素和小于目标值,则让 ` left `  右移,继续检测。
101- 3 .  直到 ` left `  和 ` right `  移动到相同位置停止检测。
102- 4 .  如果最终仍没找到,则返回 ` [-1, -1] ` 。
106+    2 .  如果元素和大于目标值,则让 $ right$  左移,继续检测。
107+    3 .  如果元素和小于目标值,则让 $ left$  右移,继续检测。
108+ 3 .  直到 $ left$  和 $ right$  移动到相同位置停止检测。
109+ 4 .  如果最终仍没找到,则返回 $ [ -1, -1] $ 。
103110
104111##### 思路 1:代码  
105112
@@ -132,15 +139,15 @@ class Solution:
132139
133140#### 2.5.2 题目大意  
134141
135- ** 描述** :给定一个字符串 ` s ` 。
142+ ** 描述** :给定一个字符串 $s$ 。
136143
137144** 要求** :判断是否为回文串(只考虑字符串中的字母和数字字符,并且忽略字母的大小写)。
138145
139146** 说明** :
140147
141148-  回文串:正着读和反着读都一样的字符串。
142149-  $1 \le s.length \le 2 * 10^5$。
143- -  ` s `  仅由可打印的 ASCII 字符组成。
150+ -  $s$  仅由可打印的 ASCII 字符组成。
144151
145152** 示例** :
146153
@@ -159,12 +166,12 @@ class Solution:
159166
160167##### 思路 1:对撞指针  
161168
162- 1 .  使用两个指针 ` left ` , ` right ` 。 ` left `  指向字符串开始位置,` right `  指向字符串结束位置。
163- 2 .  判断两个指针对应字符是否是字母或数字。 通过 ` left `  右移、` right `  左移的方式过滤掉字母和数字以外的字符。
164- 3 .  然后判断 ` s[start] `  是否和 ` s[end] `  相等(注意大小写)。
165-    1 .  如果相等,则将 ` left `  右移、` right `  左移,继续进行下一次过滤和判断。
166-    2 .  如果不相等,则说明不是回文串,直接返回 ` False ` 。
167- 4 .  如果遇到 ` left == right ` ,跳出循环,则说明该字符串是回文串,返回 ` True ` 。
169+ 1 .  使用两个指针 $ left$,$ right$。$ left$  指向字符串开始位置,$ right$  指向字符串结束位置。
170+ 2 .  判断两个指针对应字符是否是字母或数字。 通过 $ left$  右移、$ right$  左移的方式过滤掉字母和数字以外的字符。
171+ 3 .  然后判断 $ s[ start] $  是否和 $ s[ end] $  相等(注意大小写)。
172+    1 .  如果相等,则将 $ left$  右移、$ right$  左移,继续进行下一次过滤和判断。
173+    2 .  如果不相等,则说明不是回文串,直接返回 $ False$ 。
174+ 4 .  如果遇到 $ left == right$ ,跳出循环,则说明该字符串是回文串,返回 $ True$ 。
168175
169176##### 思路 1:代码  
170177
@@ -227,16 +234,16 @@ class Solution:
227234
228235##### 思路 1:对撞指针  
229236
230- 从示例中可以看出,如果确定好左右两端的直线,容纳的水量是由  ` 左右两端直线中较低直线的高度 * 两端直线之间的距离   `   所决定的。所以我们应该使得  ** 较低直线的高度尽可能的高 ** ,这样才能使盛水面积尽可能的大。
237+ 从示例中可以看出,如果确定好左右两端的直线,容纳的水量是由「 左右两端直线中较低直线的高度 * 两端直线之间的距离」 所决定的。所以我们应该使得「」 ,这样才能使盛水面积尽可能的大。
231238
232239可以使用对撞指针求解。移动较低直线所在的指针位置,从而得到不同的高度和面积,最终获取其中最大的面积。具体做法如下:
233240
234- 1 .  使用两个指针 ` left ` , ` right ` 。 ` left `  指向数组开始位置,` right `  指向数组结束位置。
235- 2 .  计算 ` left `  和 ` right `  所构成的面积值,同时维护更新最大面积值。
236- 3 .  判断 ` left `  和 ` right `  的高度值大小。
237-    1 .  如果 ` left `  指向的直线高度比较低,则将 ` left `  指针右移。
238-    2 .  如果 ` right `  指向的直线高度比较低,则将 ` right `  指针左移。
239- 4 .  如果遇到 ` left == right ` ,跳出循环,最后返回最大的面积。
241+ 1 .  使用两个指针 $ left$,$ right$。$ left$  指向数组开始位置,$ right$  指向数组结束位置。
242+ 2 .  计算 $ left$  和 $ right$  所构成的面积值,同时维护更新最大面积值。
243+ 3 .  判断 $ left$  和 $ right$  的高度值大小。
244+    1 .  如果 $ left$  指向的直线高度比较低,则将 $ left$  指针右移。
245+    2 .  如果 $ right$  指向的直线高度比较低,则将 $ right$  指针左移。
246+ 4 .  如果遇到 $ left == right$ ,跳出循环,最后返回最大的面积。
240247
241248##### 思路 1:代码  
242249
@@ -265,11 +272,13 @@ class Solution:
265272
266273>  ** 快慢指针** :指的是两个指针从同一侧开始遍历序列,且移动的步长一个快一个慢。移动快的指针被称为 「快指针(fast)」,移动慢的指针被称为「慢指针(slow)」。两个指针以不同速度、不同策略移动,直到快指针移动到数组尾端,或者两指针相交,或者满足其他特殊条件时为止。
267274
275+ ![ 快慢指针] ( https://qcdn.itcharge.cn/images/20230906173808.png ) 
276+ 
268277### 3.1 快慢指针求解步骤  
269278
270- 1 .  使用两个指针 ` slow ` 、 ` fast ` 。 ` slow `  一般指向序列第一个元素,即:` slow = 0 ` , ` fast `  一般指向序列第二个元素,即:` fast = 1 ` 。
271- 2 .  在循环体中将左右指针向右移动。当满足一定条件时,将慢指针右移,即 ` slow += 1 ` 。当满足另外一定条件时(也可能不需要满足条件),将快指针右移,即 ` fast += 1 ` 。
272- 3 .  到快指针移动到数组尾端(即 ` fast == len(nums) - 1 ` ),或者两指针相交,或者满足其他特殊条件时跳出循环体。
279+ 1 .  使用两个指针 $ slow$、$ fast$。$ slow$  一般指向序列第一个元素,即:$ slow = 0$,$ fast$  一般指向序列第二个元素,即:$ fast = 1$ 。
280+ 2 .  在循环体中将左右指针向右移动。当满足一定条件时,将慢指针右移,即 $ slow += 1$ 。当满足另外一定条件时(也可能不需要满足条件),将快指针右移,即 $ fast += 1$ 。
281+ 3 .  到快指针移动到数组尾端(即 $ fast == len(nums) - 1$ ),或者两指针相交,或者满足其他特殊条件时跳出循环体。
273282
274283### 3.2 快慢指针伪代码模板  
275284
@@ -297,22 +306,27 @@ return 合适的值
297306
298307#### 3.4.2 题目大意  
299308
300- ** 描述** :给定一个有序数组 ` nums ` 。
309+ ** 描述** :给定一个有序数组 $ nums$ 。
301310
302- ** 要求** :删除数组 ` nums `  中的重复元素,使每个元素只出现一次。并输出去除重复元素之后数组的长度。
311+ ** 要求** :删除数组 $ nums$  中的重复元素,使每个元素只出现一次。并输出去除重复元素之后数组的长度。
303312
304313** 说明** :
305314
306315-  不能使用额外的数组空间,在原地修改数组,并在使用 $O(1)$ 额外空间的条件下完成。
307316
308317** 示例** :
309318
319+ -  示例 1:
320+ 
310321``` python 
311322输入:nums =  [1 ,1 ,2 ]
312323输出:2 , nums =  [1 ,2 ,_]
313324解释:函数应该返回新的长度 2  ,并且原数组 nums 的前两个元素被修改为 1 , 2  。不需要考虑数组中超出新长度后面的元素。
325+ ``` 
314326
327+ -  示例 2:
315328
329+ ``` python 
316330输入:nums =  [0 ,0 ,1 ,1 ,1 ,2 ,2 ,3 ,3 ,4 ]
317331输出:5 , nums =  [0 ,1 ,2 ,3 ,4 ]
318332解释:函数应该返回新的长度 5  , 并且原数组 nums 的前五个元素被修改为 0 , 1 , 2 , 3 , 4  。不需要考虑数组中超出新长度后面的元素。
@@ -326,13 +340,13 @@ return 合适的值
326340
327341删除重复元素,实际上就是将不重复的元素移到数组左侧。考虑使用双指针。具体算法如下:
328342
329- 1 .  定义两个快慢指针 ` slow ` , ` fast ` 。其中 ` slow `  指向去除重复元素后的数组的末尾位置。` fast `  指向当前元素。
330- 2 .  令 ` slow `  在后, ` fast `  在前。令 ` slow = 0 ` , ` fast = 1 ` 。
331- 3 .  比较 ` slow `  位置上元素值和 ` fast `  位置上元素值是否相等。
332-    -  如果不相等,则将 ` slow `  右移一位,将 ` fast `  指向位置的元素复制到 ` slow `  位置上。
333- 4 .  将 ` fast `  右移 ` 1 `  位。
334- 5 .  重复上述 3 ~ 4  步,直到 ` fast `  等于数组长度。
335- 6 .  返回 ` slow + 1 `  即为新数组长度。
343+ 1 .  定义两个快慢指针 $ slow$,$ fast$ 。其中 $ slow$  指向去除重复元素后的数组的末尾位置。$ fast$  指向当前元素。
344+ 2 .  令 $ slow$  在后, $ fast$  在前。令 $ slow = 0$,$ fast = 1$ 。
345+ 3 .  比较 $ slow$  位置上元素值和 $ fast$  位置上元素值是否相等。
346+    -  如果不相等,则将 $ slow$  右移一位,将 $ fast$  指向位置的元素复制到 $ slow$  位置上。
347+ 4 .  将 $ fast$  右移 $1$  位。
348+ 5 .  重复上述 $3 \sim 4$  步,直到 $ fast$  等于数组长度。
349+ 6 .  返回 $ slow + 1$  即为新数组长度。
336350
337351##### 思路 1:代码  
338352
@@ -360,15 +374,17 @@ class Solution:
360374
361375## 4. 分离双指针  
362376
363- >  ** 分离双指针** :两个指针分别属于不同的数组 / 链表,两个指针分别在两个数组 / 链表中移动。
377+ >  ** 分离双指针** :两个指针分别属于不同的数组,两个指针分别在两个数组中移动。
378+ 
379+ ![ 分离双指针] ( https://qcdn.itcharge.cn/images/20230906180852.png ) 
364380
365381### 4.1 分离双指针求解步骤  
366382
367- 1 .  使用两个指针 ` left_1 ` 、 ` left_2 ` 。 ` left_1 `  指向第一个数组 / 链表的第一个元素 ,即:` left_1  = 0` , ` left_2 `  指向第二个数组 / 链表的第一个元素 ,即:` left_2  = 0` 。
368- 2 .  当满足一定条件时,两个指针同时右移,即 ` left_1  += 1` 、 ` left_2  += 1` 。
369- 3 .  当满足另外一定条件时,将 ` left_1 `  指针右移,即 ` left_1  += 1` 。
370- 4 .  当满足其他一定条件时,将 ` left_2 `  指针右移,即 ` left_2  += 1` 。
371- 5 .  当其中一个数组 / 链表遍历完时或者满足其他特殊条件时跳出循环体 。
383+ 1 .  使用两个指针 $left\underline{}1$、$left\underline{}2$。$left\underline{}1$ 指向第一个数组的第一个元素 ,即:$left\underline{}1  = 0$,$left\underline{}2$ 指向第二个数组的第一个元素 ,即:$left\underline{}2  = 0$ 。
384+ 2 .  当满足一定条件时,两个指针同时右移,即 $left\underline{}1  += 1$、$left\underline{}2  += 1$ 。
385+ 3 .  当满足另外一定条件时,将 $left\underline{}1$  指针右移,即 $left\underline{}1  += 1$ 。
386+ 4 .  当满足其他一定条件时,将 $left\underline{}2$  指针右移,即 $left\underline{}2  += 1$ 。
387+ 5 .  当其中一个数组遍历完时或者满足其他特殊条件时跳出循环体 。
372388
373389### 4.2 分离双指针伪代码模板  
374390
@@ -400,7 +416,7 @@ while left_1 < len(nums1) and left_2 < len(nums2):
400416
401417#### 4.4.2 题目大意  
402418
403- ** 描述** :给定两个数组 ` nums1 `  和 ` nums2 ` 。
419+ ** 描述** :给定两个数组 $ nums1$  和 $ nums2$ 。
404420
405421** 要求** :返回两个数组的交集。重复元素只计算一次。
406422
@@ -411,11 +427,17 @@ while left_1 < len(nums1) and left_2 < len(nums2):
411427
412428** 示例** :
413429
430+ -  示例 1:
431+ 
414432``` python 
415433输入:nums1 =  [1 ,2 ,2 ,1 ], nums2 =  [2 ,2 ]
416434输出:[2 ]
417435示例 2 :
436+ ``` 
437+ 
438+ -  示例 2:
418439
440+ ``` python 
419441输入:nums1 =  [4 ,9 ,5 ], nums2 =  [9 ,4 ,9 ,8 ,4 ]
420442输出:[9 ,4 ]
421443解释:[4 ,9 ] 也是可通过的
@@ -425,12 +447,12 @@ while left_1 < len(nums1) and left_2 < len(nums2):
425447
426448##### 思路 1:分离双指针  
427449
428- 1 .  对数组 ` nums1 ` 、 ` nums2 `  先排序。
429- 2 .  使用两个指针 ` left_1 ` 、 ` left_2 ` 。 ` left_1 `  指向第一个数组的第一个元素,即:` left_1  = 0` , ` left_2 `  指向第二个数组的第一个元素,即:` left_2  = 0` 。
430- 3 .  如果 ` nums1[left_1]  `  等于  ` nums2[left_2]  ` ,则将其加入答案数组(注意去重),并将 ` left_1 `  和 ` left_2 `  右移。
431- 4 .  如果 ` nums1[left_1]  `  小于  ` nums2[left_2]  ` ,则将 ` left_1 `  右移。
432- 5 .  如果 ` nums1[left_1]  `  大于  ` nums2[left_2]  ` ,则将 ` left_2 `  右移。
433- 6 .  最后输出答案数组 。
450+ 1 .  对数组 $ nums1$、$ nums2$  先排序。
451+ 2 .  使用两个指针 $left\underline{}1$、$left\underline{}2$。$left\underline{}1$  指向第一个数组的第一个元素,即:$left\underline{}1  = 0$,$left\underline{}2$  指向第二个数组的第一个元素,即:$left\underline{}2  = 0$ 。
452+ 3 .  如果 $ nums1[ left\underline{}1 ]  ==  nums2[ left\underline{}2 ] $ ,则将其加入答案数组(注意去重),并将 $left\underline{}1$  和 $left\underline{}2$  右移。
453+ 4 .  如果 $ nums1[ left\underline{}1 ]  <  nums2[ left\underline{}2 ] $ ,则将 $left\underline{}1$  右移。
454+ 5 .  如果 $ nums1[ left\underline{}1 ]  >  nums2[ left\underline{}2 ] $ ,则将 $left\underline{}2$  右移。
455+ 6 .  最后返回答案数组 。
434456
435457##### 思路 1:代码  
436458
0 commit comments