一、题目描述:
给你一个整数数组 n u m s nums nums ,判断是否存在三元组 [ n u m s [ i ] , n u m s [ j ] , n u m s [ k ] ] [nums[i], nums[j], nums[k]] [nums[i],nums[j],nums[k]] 满足 i ≠ j i \neq j i=j、 i ≠ k i \neq k i=k 且 j ≠ k j \neq k j=k ,同时还满足 n u m s [ i ] + n u m s [ j ] + n u m s [ k ] = 0 nums[i] + nums[j] + nums[k] = 0 nums[i]+nums[j]+nums[k]=0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
- 示例 1:
- 输入: n u m s = [ − 1 , 0 , 1 , 2 , − 1 , − 4 ] nums = [-1,0,1,2,-1,-4] nums=[−1,0,1,2,−1,−4]
- 输出: [ [ − 1 , − 1 , 2 ] , [ − 1 , 0 , 1 ] ] [[-1,-1,2],[-1,0,1]] [[−1,−1,2],[−1,0,1]]
- 解释:
- n u m s [ 0 ] + n u m s [ 1 ] + n u m s [ 2 ] = ( − 1 ) + 0 + 1 = 0 nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 nums[0]+nums[1]+nums[2]=(−1)+0+1=0 。
- n u m s [ 1 ] + n u m s [ 2 ] + n u m s [ 4 ] = 0 + 1 + ( − 1 ) = 0 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 nums[1]+nums[2]+nums[4]=0+1+(−1)=0 。
- n u m s [ 0 ] + n u m s [ 3 ] + n u m s [ 4 ] = ( − 1 ) + 2 + ( − 1 ) = 0 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 nums[0]+nums[3]+nums[4]=(−1)+2+(−1)=0 。
- 不同的三元组是 [ − 1 , 0 , 1 ] [-1,0,1] [−1,0,1] 和 [ − 1 , − 1 , 2 ] [-1,-1,2] [−1,−1,2] 。
- 注意,输出的顺序和三元组的顺序并不重要。
- 示例 2:
- 输入: n u m s = [ 0 , 1 , 1 ] nums = [0,1,1] nums=[0,1,1]
- 输出: [ ] [] []
- 解释:唯一可能的三元组和不为 0 。
- 示例 3:
- 输入: n u m s = [ 0 , 0 , 0 ] nums = [0,0,0] nums=[0,0,0]
- 输出: [ [ 0 , 0 , 0 ] ] [[0,0,0]] [[0,0,0]]
- 解释:唯一可能的三元组和为 0 。
- 提示:
- 3 ≤ n u m s . l e n g t h ≤ 3000 3 \leq nums.length \leq 3000 3≤nums.length≤3000
- − 1 0 5 ≤ n u m s [ i ] ≤ 1 0 5 -10^5 \leq nums[i] \leq 10^5 −105≤nums[i]≤105
二、解决思路和代码
1. 解决思路
- 分析:题目中指定三数之和是0,那么这三个数字有大有小,我们可以先对数组中的数字进行排序,然后使用三个指针遍历
-
step1: 对数组中的数值排序。(python中可以使用 nums.sort())
-
step2: 三指针查找和为 0 的三个数
-
2. 代码
from typing import *
class Solution:
## 快速排序算法
def quickSort(self, nums: List[int], start: int, end: int):
if start>end: return
left, right = start, end
temp = nums[left]
while left < right:
while left<right and nums[right]>=temp: right-=1
if left < right:
nums[left] = nums[right]
left += 1
while left<right and nums[left]<=temp: left += 1
if left<right:
nums[right] = nums[left]
right -= 1
nums[left] = temp
self.quickSort(nums, start, left-1)
self.quickSort(nums, left+1, end)
return
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums2 = nums.copy()
res = []
## step1: 对数组进行排序
self.quickSort(nums2, 0, len(nums2)-1)
## step2: 三指针遍历
for i in range(len(nums2)):
left, right = i+1, len(nums2)-1
while left<right:
if nums2[i]+nums2[left]+nums2[right]==0:
if [nums2[i],nums2[left],nums2[right]] not in res:
res.append([nums2[i],nums2[left],nums2[right]])
left += 1
right -= 1
while left<right and nums2[i]+nums2[left]+nums2[right]>0: right-=1
while left<right and nums2[i]+nums2[left]+nums2[right]<0: left+=1
return res
```