- 题目要求:
-
思路
- 定义一个res[]用来保存结果集
- 先把数组排个序,这样遇到重复的数字可以直接到下一个
- 遍历数组,只遍历数组下标位置从0到数组长度-2的位置即可
- 如果nums[i] + nums[i+1] + nums[i+2]之和大于0,说明当前遍历到的位置之后的所有元素的三个元素之和一定大于0,因为数组是排好序的,此时break出循环
- 如果当前的元素与数组最后两个元素之和小于零,说明当前元素太小了,和最大的两个数之和都小于零,此时直接遍历下一个数组元素(continue)
- 如果数组下标大于0,而且,如果当前元素与前一个元素相等,此时直接遍历下一个数组元素(continue)
- 在循环中定义一个l(left),l的值为当前数组元素下标i的下一个,定义一个r(right),为数组元素的最后一位,也就是nums[i]为当前的数值,剩余的两个值要从左向右,从右向左往中间找,直至l与r重合
-
用l和r遍历i右侧的数组元素时,定义一个tmp来保存当前nums[i]、nums[l]、nums[r]的和
- 如果当前的tmp等于0,说明三个数字找到了,把[nums[i],nums[l],nums[r]]这三个数组成的数组append到res结果集中,然后用while循环找到下一个数组元素不等于当前nums[l]的元素的下标,判断条件为l小于l,当前的l和下一个l+1的数组元素值是否相等,如果相等,直接把l加一,r也是一样
- 寻找不重复元素的while循环结束之后,当前的l是最后一位等于当前的nums[l]的值,所以把l加一,r也是同理
- 如果当前的tmp值小于0,说明当前的r和l的和偏小,l加一
- 如果当前的tmp值大于0,说明当前的r和l的和偏大,r减一
- 最后返回结果集res
- 核心代码:
#n为数组长度
n = len(nums)
#用来保存结果集
res = []
#把数组排序
nums.sort()
#遍历排序的数组
for i in range(n-2):
#如果当前的值与下一个值还有下下个值得和大于0,后面就都没有和等于0的值了,因为数组是排好序的,此时跳出循环
if nums[i] + nums[i+1] + nums[i+2] > 0:
break
#如果当前的值与数组的最后两个值之和都小于0,说明当前的值太小了,继续遍历下一位元素
if nums[i] + nums[n-2] + nums[n-1] < 0:
continue
#如果当前的元素下标不为0,而且当前的元素与前一个元素的值相等,说明元素重复了,直接遍历下一个
if i > 0 and nums[i] == nums[i-1]:
continue
#l用来表示i的下一个,r用来表示数组的最后一位元素,r和l向中心靠拢,寻找下标为i,r,l和为0的元素
l = i + 1
r = n - 1
#当l小于r时,循环
while l < r:
#定义一个tmp来保存当前的三个数的和
tmp = nums[i] + nums[l] + nums[r]
#如果和为0
if tmp == 0:
#和为0说明找到了三个数,把这三个数作为一整个数组,加到结果集中
res.append([nums[i],nums[l],nums[r]])
#然后判断l的下一位是否是重复的,如果重复l加一
while l < r and nums[l] == nums[l+1]:
l += 1
#当前的nums[l]为最后一位与之前的nums[l]相等的值,所以l还要加一
l += 1
#r也是同理
while l < r and nums[r] == nums[r-1]:
r -= 1
r -= 1
#如果三个数的和小于0,说明三个数的和偏小,l要向右移
elif tmp < 0:
l += 1
#如果三个数的和大于0,说明三个数的和偏大,r向左移
else:
r -= 1
#返回结果集
return res
- 完整代码:
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
n = len(nums)
res = []
nums.sort()
for i in range(n-2):
if nums[i] + nums[i+1] + nums[i+2] > 0:
break
if nums[i] + nums[n-2] + nums[n-1] < 0:
continue
if i > 0 and nums[i] == nums[i-1]:
continue
l = i + 1
r = n - 1
while l < r:
tmp = nums[i] + nums[l] + nums[r]
if tmp == 0:
res.append([nums[i],nums[l],nums[r]])
while l < r and nums[l] == nums[l+1]:
l += 1
l += 1
while l < r and nums[r] == nums[r-1]:
r -= 1
r -= 1
elif tmp < 0:
l += 1
else:
r -= 1
return res
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。