LeetCode #15 3Sum
题目
解题方法
a + b + c = 0的问题可以等价于a + b = 0 - c的问题,令target = 0 - c,套用#1 Two Sum的解题方法即可破题。
需要注意的是两道题的返回值有所不同,此题返回值是一个嵌套列表,由多个不重复的子列表组成,每个列表中三个数相加都是0。因此需要考虑列表去重问题,有两种办法:
- 在执行过程中跳过重复项;
- 先获取所有结果,再去掉其中重复项。
我采用的方法是将两种去重方法结合,在第一重循环中跳过重复项,然后执行常规的Two Sum解题,最后再利用python的集合set元素不重复的特性去重。
一般的list去重只需要用list(set(列表))即可,代码如下:
res = [1,2,3,4,5,1,2,3]
list(set(res))
嵌套列表去重需要用到tuple,代码如下:
temp_set = set(tuple(i) for i in old_list)
new_list = [list(t) for t in temp_set]
需要注意的是,这样写需要列表中每一个子列表都是按照一定顺序排列好的,例如[[1,2,3], [1,3,2], [2,3,1]]如果不排序为[[1,2,3], [1,2,3], [1,2,3]],将被set认定为不重复的元素项,与此题题意不符,因此需要在去重前先对每一个子列表进行排序:
for i, t in enumerate(old_list):
t.sort()
代码
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
nums.sort()
for i in range(len(nums)-2):
if i and nums[i] == nums[i-1]:
continue
dic = {}
target = 0 - nums[i]
for j in range(i+1, len(nums)):
if target - nums[j] in dic:
res.append([nums[i], nums[j], target-nums[j]])
dic[nums[j]] = j
temp = set(tuple(i) for i in res)
ret = [list(t) for t in temp]
return ret
改进版,利用set.add()方法在添加重复元素时不执行操作的特性,省去嵌套列表去重操作,节省运行时间。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
if len(nums) < 3:
return []
nums.sort()
res = set()
for i, v in enumerate(nums[:-2]):
if i >= 1 and v == nums[i-1]:
continue
d = {}
for x in nums[i+1:]:
if x not in d:
d[-v-x] = 1
else:
res.add((v, -v-x, x))
return map(list, res)

浙公网安备 33010602011771号