本篇文章中,我们以力扣的三道题为例,分析双指针的应用。
三道题分别是删除有序数组中的重复项、移除元素、盛最多水的容器。
需要注意这几道题的指针都是针对于链表中的索引。
目录
在前两道题中,两个指针i, j,保持i <= j,
i的作用主要用于指示新的列表中填入元素的相对位置,和有效列表的长度
j的作用则是向后搜索,搜索到符合条件的数值就填入到i所指示的相对位置中。
1、删除有序数组中的重复项
具体来说,在题目删除有序数组中的重复项中,
i,j在移动的过程中,如果发现nums[j] = nums[i],那么j就持续移动,直到找到一个不和nums[i]相等的元素,
此时,让nums[i+1](nums[i]后的一个元素)等于nums[j],此时,让i 自增1,j自增1(开始比较下一个值,使得它不存在重复的元素)
直到j搜索完整个列表。
注意,这道题目的前提是列表必须是有序的,如果是无序的,做法则不成立。
对应代码如下:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
lenth = len(nums)
i, j = 0 , 0
while(j < lenth):
if(nums[i] == nums[j]):
j = j + 1
else:
nums[i+1] = nums[j]
i = i + 1
j = j + 1
return i+1
2、 移除元素
下面类似地,我们来分析 移除元素
同样是两个指针i, j,保持i <= j
j搜索整个列表,如果和题目要求不能有的数不一样,则在i的位置填入该数,
i每填入一个数,i自增1(i同样用来指示要填入数的位置和 有效列表的长度)
(这道题目不要求列表有序)
对应代码如下:
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
i = 0
lenth = len(nums)
for j in range(lenth):
if(nums[j] != val):
nums[i] = nums[j]
i = i + 1
return i
优化:
采用这种做法,容易发现,有可能若i位置的数不是题目数val,也会被改掉 (上述做法一个潜在思想是:用原来列表的空间,重新把所有不是val的数依次排列一遍)
那么有一种想法是,对于i位置不是val的数就不要动,如果等于val,j依次从列表最后开始找,把数填上去,如果填上去的数依然等于val,j再往后找。
过程中要求i < = j
(这种做法的潜在思想是,把将要构成的有效列表的每一位,都置换成不等于val的数)
对应代码如下:
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
# 对双指针的算法进行优化,
# 不会改变时间复杂度,但是对原本不是val元素的数值大部分不会更改
xa = 0
xb = len(nums) - 1
while(xa <= xb):
if(nums[xa] == val):
nums[xa] = nums[xb]
xb = xb - 1
else:
xa = xa + 1
return xa
3、盛最多水的容器
对于第三题 盛最多水的容器
或许可以通过搜索的方式在O(n^2)的时间复杂度内,找到所有长度内i,j的组合
但是我们直到,我们以一种更可能的方式搜索,只在O(n)的时间复杂度内解决这道题:
双指针从列表的两头开始搜索,一定会是一个指针在左,一个指针在右
由于我们要找出最大的面积,所以两个指针指示的值作比较,较矮的指针优先移动,
直到两个指针相遇,就一定可以找到最大的面积。
对应代码如下:
class Solution:
def maxArea(self, height: List[int]) -> int:
xa = 0
xb = len(height)-1
Smax = 0
while(xa < xb):
width = xb - xa
h = min(height[xa], height[xb])
Scurr = width * h
if(Scurr > Smax):
Smax = Scurr
if(height[xa] < height[xb]):
xa = xa + 1
else:
xb = xb - 1
return Smax
所以在上两题中,双指针是必要,第三题双指针降低了时间复杂度。
欢迎交流、指正!
参考题解:
力扣https://leetcode-cn.com/problems/remove-element/solution/yi-chu-yuan-su-by-leetcode-solution-svxi/
力扣https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/solution/力扣
https://leetcode-cn.com/problems/container-with-most-water/solution/sheng-zui-duo-shui-de-rong-qi-by-leetcode-solution/