题目:15.三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意: 答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解题思路
这里主要是用了一种固定的套路:双指针。
- 将nums排序(从小到大)。
- 用双指针:
1>.先定义3个指针,一个固定指针i,两个左右指针L,R;
2>.令i固定数组的最左边,作为新动态数组的左边界,即i=0; - 同时,L=i+1,R=len(nums) -1,即分别指向新数组的两端;
- 用i遍历数组,作为外循环,不断的将左边界向右推进,逐渐缩小新数组的长度;
- 判断 sum=nums[i]+nums[L]+nums[R] 的大小;
- sum==0, 符合要求,存入res,之后,L+1,R-1;
- sum<0, L+1;
(因为数组是从小到大排序过的,当sum<0,三个数整体来说是偏小的,自然要让三数中最小的数nums[L]变大,即指针L向右移动) - sum>0,R-1;
(同理,sum偏大,就让最大的值nums[R]变小)
动画
代码(Python)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res=[]
#错误判断,数组长度小于3,直接返回
if(not nums or len(nums)<3):
return []
nums.sort()
res=[]
#外循环
for i in range(len(nums)-2):
#初始化左右指针
L=i+1
R=len(nums)-1
#边界判断
while L<R:
sum = nums[i]+nums[L]+nums[R]
#符合要求,向res赋值,同时左右指针向内推进
if sum ==0:
res.append([nums[i],nums[L],nums[R]])
L=L+1
R=R-1
#sum偏小,L向右移动
elif sum < 0:
L=L+1
#sum偏大,L向左移动
else:
R=R-1
return res
相信有的小伙伴已经发现了。当数组中有重复的元素时,其实是可以排除掉的。
更改代码如下:
代码(Python)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res=[]
if(not nums or len(nums)<3):
return []
nums.sort()
res=[]
for i in range(len(nums)-2):
#nums[i]都>0,三数都是正数,sum不可能=0
if(nums[i]>0):
return res
#排除重复的nums[i]
if(i>0 and nums[i]==nums[i-1]):
continue
L=i+1
R=len(nums)-1
while L<R:
sum = nums[i]+nums[L]+nums[R]
if sum ==0:
res.append([nums[i],nums[L],nums[R]])
L=L+1
R=R-1
elif sum < 0:
L=L+1
else:
R=R-1
#排除重复的nums[L],nums[R]
while(L<R and nums[L]==nums[L+1]):
L=L+1
while(L<R and nums[R]==nums[R-1]):
R=R-1
return res
总结
好了,关于双指针的问题,就到这里了。leetcode咱也是刚开始刷,我准备接下来多做几道关于双指针的题目,有时间也会继续做出动画的!最后,有错误遗漏的地方欢迎大家指正!完结撒花~
有兴趣的也可以康康我的下一篇:最接近的三数之和
后续
同时,贴上咱的个人博客,欢迎客官大老爷们来访~
青枫阁