题目分析:
这道题目让我想到了2Sum,所以向先固定一个数再按2Sum找,但是不可避免的出现重返列表。重复列表解决起来比较麻烦,再把结果双循环去重会TLE。所以去考虑先排序再固定一个数之后夹逼就可以了。
代码说明:
1、第一个if,如果笃定元素大于0,后面的一定都大于零(排过序),就不用再找另外两个。第二个if,目的是判断这个固定用的元素与上一次的相同避免无用功。target是固定的元素.j,k是首尾夹逼的指针,j要指向固定元素的下一位。
if nums[i] > 0: return res
if i > 0 and nums[i] == nums[i-1]: continue
target = 0 - nums[i]
j, k = i + 1, l - 1
2、这是为了避免重复元素出现。
while j < k and nums[j] == nums[j + 1]: j += 1
while j < k and nums[k] == nums[k - 1]: k -= 1
3、小于目标元素左指针右移(增大和),否则大于(等于上面判断过)右指针左移(减小和)。
elif nums[j] + nums[k] < target: j += 1
else: k -= 1
测试代码:
class Solution:
def threeSum(self, nums):
if not nums: return nums
nums.sort()
l = len(nums)
res = []
for i in range(l):
if nums[i] > 0: return res
if i > 0 and nums[i] == nums[i-1]: continue
target = 0 - nums[i]
j, k = i + 1, l - 1
while(j < k):
if nums[j] + nums[k] == target:
res.append([target, nums[j], nums[k]])
while j < k and nums[j] == nums[j + 1]: j += 1
while j < k and nums[k] == nums[k - 1]: k -= 1
j += 1
k -= 1
elif nums[j] + nums[k] < target: j += 1
else: k -= 1
return res
print(Solution().threeSum([-1, 0, 1, 2, -1, -4])) #提交时请删除该行