暴力求解 时间复杂度O(N^3)
会超时。。。。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
distinct_dict = {}
for i in range(len(nums) - 2):
for j in range(i + 1, len(nums) - 1):
for k in range(j + 1, len(nums)):
if nums[i] + nums[j] + nums[k] == 0:
res_item = [nums[i], nums[j], nums[k]]
res_item.sort()
if tuple(res_item) not in distinct_dict:
# 使用 int tuple作为dict的key进行去重
res.append(res_item)
distinct_dict[tuple(res_item)] = 1
return res
使用dict替代第三重循环 直接查找对应的数字 时间复杂度 O(N^2)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
# 排序减少重复
nums.sort()
# 相同的值 会保留后面的索引
value_by_index = {nums[i]: i for i in range(len(nums))}
for i in range(len(nums) - 2):
# 值和之前相同则跳过
if i > 0 and nums[i] == nums[i - 1]:
continue
for j in range(i + 1, len(nums) - 1):
# 值和之前相同则跳过
if j > i + 1 and nums[j] == nums[j - 1]:
continue
c = - (nums[i] + nums[j])
c_index = value_by_index.get(c)
# 类似第三重循环 找到的值 下标需要大于j
if c_index and c_index > j:
res.append([nums[i], nums[j], nums[c_index]])
return res
排序+双指针 时间复杂度O(N^2)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
# 排序 数字由小到大
# 固定k i j 之后 若三数之和小于0 则右移i 反之左移j
# 移动的时候若元素值和之前相同则跳过
nums.sort()
for k in range(len(nums) - 2):
# 排序过 数字由小到大 若k已经大于零 则后面都是正数 不可能和为0
if nums[k] > 0:
break
# k右移 如果和之前的值相同则continue 相当于k += 1
if k > 0 and nums[k] == nums[k - 1]: continue
# 双指针左右夹逼
i, j = k + 1, len(nums) - 1
while i < j:
s = nums[k] + nums[i] + nums[j]
if s < 0:
# 和小于零 i右移到更大的值上面 提升和
i += 1
# i右移 和左值比较 相等则跳过
# 注意大前提 i < j
while i < j and nums[i] == nums[i - 1]: i += 1
elif s > 0:
j -= 1
while i < j and nums[j] == nums[j + 1]: j -= 1
else:
res.append([nums[k], nums[i], nums[j]])
# 和为0的情况 记录
# 之后 i,j 需要同时内移 并跳过相同的值
i += 1
while i < j and nums[i] == nums[i - 1]: i += 1
j -= 1
while i < j and nums[j] == nums[j + 1]: j -= 1
return res