“删除有序数组中的重复项”和“三数之和”都可以借助预排序+双指针的方法来解决。首先进行排序,然后通过左右指针逐步筛选满足条件的数组值。
双指针
前提:数组有序性。
含义:在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(左右指针)的指针进行扫描,从而达到相应的目的。
三数之和这里使用的是左右指针,因此此处先介绍左右指针。左右指针在数组中实际是指两个索引值,一般初始化为 left = 0, right = len(nums) - 1
(三数之和含三个数,以i为起点,left=i+1,right=len(nums)-1)
伪代码
伪代码大致如下:
function fn (list) {
var left = 0;
var right = list.length - 1;
left = 0
right = len(nums)-1
while left <= right:#遍历数组
left++
#一些条件判断和处理
right--
双指针在数据结构中除了在两数之和、三数之和此类中应用,还有就是二分查找中应用也较多。
三数之和
题目
解答思路:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort() # 排序
out = []
i = 0
while i < len(nums) - 2: # i,j,k的位置[i, j,...,k],i后至少1个元素,所以<len(nums)-2
if i == 0 or nums[i] != nums[i - 1]:#第一个元素 或 和前面元素不相同
j = i + 1
k = len(nums) - 1
while j < k:
if nums[i] + nums[j] + nums[k] < 0:
j += 1 # <0要放大一点,所以j + 1
elif nums[i] + nums[j] + nums[k] > 0:
k -= 1
else:
res.append([nums[i], nums[j], nums[k]])
j += 1
k -= 1
while j < k and nums[j] == nums[j - 1]:
j += 1 # 避免nums中的数重复,res中有想同的结果
while j < k and nums[k] == nums[k + 1]:
k -= 1
i += 1
return out
结果: