
题解:
首先利用字典计算出每个数字出现的次数。
对于0出现的次数大于等于3时就将[0,0,0]加入到结果列表中
找出负数和正数并且过滤掉重复的数字。
然后遍历负数和正数列表,求0与正数和负数之和的差,看该差是不是在字典中出现过。如果出现则判断该差是不是等于正数或者负数,如果等于则需要保证该差在原来列表中出现的次数大于等于2。如果该差既不等于正数也不等于负数,则将其加入到结果列表。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums_hash = {}
result = list()
for num in nums:
nums_hash[num] = nums_hash.get(num, 0) + 1
if 0 in nums_hash and nums_hash[0] >= 3:
result.append([0, 0, 0])
neg = list(filter(lambda x: x < 0, nums_hash))
pos = list(filter(lambda x: x >= 0, nums_hash))
for i in neg:
for j in pos:
dif = 0 - i - j
if dif in nums_hash:
if dif in (i, j) and nums_hash[dif] >= 2:
result.append([i, j, dif])
if dif < i or dif > j:
result.append([i, j, dif])
return result
使用双指针,用来得到三数之中的两个数。因为要保证得到的子数组是bu不重复的,所以想对数组进行排序,从数组的第一个元素i开始,该元素作为三数之中的第一个数,如果该数大于0,则一定不会存在和为0的子数组,否则,利用两个指针,一个指针j指向该元素后面的位置,一个指针k指向排序数组的最后一个位置,然后计算这三个数之和,如果和为0,则加入到结果数组,这时候需要更新j和k,j往后移,如果后移之后元素值和移之前的元素值相同则继续往后移,为了避免出现重复子数组,k往前移,同时也要考虑如果移动之后元素值没变,那继续往前移,同时要保证j小于k,如果和小于0,则j往后移,如果和大于0,则k往前移,需要保证j永远小于k.
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
new_list = nums
if len(new_list) < 3:
return []
new_list.sort()
res = []
for i in range(len(new_list) - 2):
if new_list[i] > 0:
break
if i > 0:
if new_list[i] == new_list[i - 1]:
continue
j = i + 1
k = len(new_list) - 1
while j < k:
sums = new_list[i] + new_list[j] + new_list[k]
if sums == 0:
res.append([new_list[i], new_list[j], new_list[k]])
j = j + 1
k = k - 1
while j < k and nums[j] == nums[j - 1]:
j = j + 1
while j < k and nums[k] == nums[k + 1]:
k = k - 1
elif sums > 0:
k = k - 1
else:
j = j + 1
return res
三数之和算法解析
本文深入探讨了求解三数之和问题的两种高效算法。一种是通过字典统计和筛选,另一种是采用排序与双指针技巧,避免重复解并确保结果的准确性。文章详细介绍了每种方法的实现步骤和关键代码。
222

被折叠的 条评论
为什么被折叠?



