当前位置: 代码迷 >> 综合 >> Leetcode 15. 3Sum (python)
  详细解决方案

Leetcode 15. 3Sum (python)

热度:45   发布时间:2023-11-26 06:08:39.0

题目

在这里插入图片描述

解法1:hash table + sort triplets

这解法T了,应该是T在遍历之前储存的pair那边。不过我个人感觉这种做法比较直观

class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:pairs = collections.defaultdict(list)n = len(nums)ans = set()for i in range(n):for j in range(i+1,n):pairs[nums[i]+nums[j]].append((i,j))for i in range(n):if (0-nums[i]) not in pairs:continuefor pair in pairs[0-nums[i]]:if i != pair[0] and i!=pair[1]:ans.add(tuple(sorted((nums[i],nums[pair[0]],nums[pair[1]]))))return ans;

下面两种解法参考Leetcode官方

解法2:双指针+排序

两个关键点:

  • 排序来有效避免重复组合的出现
  • 双指针求two sum减少时间复杂度
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:res = []nums.sort()n = len(nums)for i in range(n):# we will search three numbers start from index i. So if nums[i]>0 and the nums is sorted, not valid triplets will appearif nums[i]>0:break# only use the first accounted number to avoid duplicatesif i==0 or nums[i-1]!=nums[i]:# use two pointer to search for pairs for nums[i]lo = i+1hi = n-1while lo<hi:_sum = nums[i] + nums[lo] +nums[hi]if _sum < 0:lo += 1elif _sum > 0:hi -= 1else:res.append((nums[i],nums[lo],nums[hi]))lo += 1hi -= 1# again, we need to avoid duplicates. But we only need to do it for lo or hi, because once one of them is changed, the other will change towhile lo<hi and nums[lo]==nums[lo-1]:lo += 1return res

解法3:hash table + 排序

外循环和避免重复组合的方法与解法2一致,只是two sum用hash table来作

class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:res = []nums.sort()n = len(nums)for i in range(n):# we will search three numbers start from index i. So if nums[i]>0 and the nums is sorted, not valid triplets will appearif nums[i]>0:break# only use the first accounted number to avoid duplicatesif i==0 or nums[i-1]!=nums[i]:# use hash table to search for pairs for nums[i]# seen use to keep the second element that has appeared, so the we can search for the pairs in O(n) rather than O(n^2)seen = {
    }j = i+1while j<n:remain = -nums[i]-nums[j]if remain in seen:res.append((nums[i],nums[j],remain))# again, we need to avoid duplicates,here we must compare nums[j+1] and nums[j] rather than nums[j-1] and nums[j] because j is initially set to i+1. we don't move j when nums[j] happens to be equal to nums[i]while j+1<n and nums[j+1]==nums[j]:j += 1seen[nums[j]] = True;j += 1return res