给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。
- O(n^2)的基操做法卡倒数第二个样例TLE了 思路就是两数之和sum 寻找-sum是否存在数组中 因为答案要去重
在加入答案里还带了个sorted 数据规模是3e3 所以应该O(n^2)做法本身是没有问题的 但是不剪枝过于暴力和太多无用计算了
如果对原数组直接排序和set()去重会忽略了mp[-pi*2]>0的情况 总之是个憨憨做法
nums=input().split()
sz=len(nums)
dict = {}
for i in range(sz):
nums[i]=int(nums[i])
dict[nums[i]]=i
ans=[]
for i in range(sz):
for j in range(i+1,sz):
num1=nums[i]
num2=nums[j]
t=-num1-num2 #num1+num2+t = 0
if t not in dict:
continue
else:
if dict[t]==i or dict[t]==j:
continue
else:
add=sorted([num1,num2,t],reverse=False)
if add not in ans:
ans.append(add)
return ans
保存下来
然后去leetcode的评论区学习了一个启发式做法:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
zeros, positives, negatives = 0, {}, {}
for num in nums:
if num == 0:
zeros += 1
elif num > 0:
positives.setdefault(num, 0) # setdefault , if num not in positives: positives[num]=0
positives[num] += 1
else:
negatives.setdefault(num, 0)
negatives[num] += 1
# 相加为0的三元组可能的组成形式:
# 3个0,两个负数一个正数,两个正数一个负数,一正一负加一零
results = []
if zeros >= 3:
results.append([0] * 3)
if len(positives) != 0 and len(negatives) != 0:
for pi in positives:
count = positives[pi]
if count >= 2 and (-2 * pi) in negatives:
results.append([pi] * 2 + [-2 * pi])
if -pi in negatives and zeros > 0:
results.append([pi, -pi, 0])
for pj in positives:
if pj <= pi: #剪枝且去重
continue
if -1 * (pi + pj) in negatives:
results.append([-1 * (pi + pj), pi, pj])
for ni in negatives:
count = negatives[ni]
if count >= 2 and (-2 * ni) in positives:
results.append([ni] * 2 + [-2 * ni])
for nj in negatives:
if nj <= ni: #
continue
if -1 * (ni + nj) in positives:
results.append([-1 * (ni + nj), ni, nj])
return results