题目描述:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
解题思路:排序+双指针
大概想法:排序后,遍历数组,从头到尾先固定第一个数的值,在剩下的队伍里使用两个指针,找到满足三数之和为0的另外两个数存入数组;然后继续下一个第一个数。。。
需要考虑的是去重问题。因此每挪动一次指针,要满足指针指到的位置是下一个不重复的数字。
具体实现:
- 数组排序
- 固定第一个数a→确定第二个数的指针b(从左到右)和第三个数的指针c(从右到左)→判断此时加和的状态→
可以确定的是,因为数组已经排好序:
1)三数之和大于0时,指针c往左挪到下一个不重复数字,找更小的数;
2)等于0时记录下这一组数据,指针b往右挪找下一组;
3)小于(等于)0时,如果指针c再往左找到的只能是和更小的数,不会再有和为0的情况,因此指针b往右挪找(和)更大的数 - 直到a找到边界
一些可以考虑的情况:
1.数组元素小于3
2.a,b,c的边界值:a从0到倒数第二个;b从a+1算起;c从len(nums)-1算起;保证b<c,b、c就不会出现索引异常的情况。
3.指针不重复的条件
数组排序;
'''
三数之和
'''
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
ans = []
n=len(nums)
if (not nums or n<3):
return []
nums.sort() #排序
for a in range(n):
if nums[a]>0:
break
if a>=1 and nums[a]==nums[a-1]: #找到a的固定点,并保证不与前面重复
continue
c = n-1 #每新开一轮a,b、c就要重新定义
b=a+1
while b<c: #指针b的循环
if b>a+1 and nums[b]==nums[b-1]:
b+=1
continue #直到找到不与前面重复的指针b
while b < c: #指针c的循环
if c<n-1 and nums[c]==nums[c+1]:
c-=1
continue #直到找到不与后面重复的指针c
#以下判断和的情况,决定不同情况下指针的操作
if nums[a]+nums[b]+nums[c]==0: #等于0时,记录一组数据
ans.append([nums[a], nums[b], nums[c]])
b+=1 #挪动指针b,找下一组可能性
break
elif nums[a]+nums[b]+nums[c] > 0:
c-=1 #比0大时,指针c还能往左挪
else: #和小于0,指针c再往左所有的和都比0小,因此挪b
b+=1
break
return ans