刷leetcode题目为3sum的一些感想
第一次写博客,今天在刷leetcode的时候看到很经典的一道题目3sum,从给出的数字列表中找出和为0的三元组。我开始的思路是先对列表进行排序,然后定住一个数字,剩余
两个数字使用夹逼的方法往中间靠拢。这个想法本质上就是嵌套循环,时间复杂度是O(n²)。在leetcode提交提示超时,想是不是要用动态规划的方法去提
升一下效率,毕竟n²的效率实在太低了。但是水平有限,想不到后来发现有很多重复的数字可以跳过,是不必运算的。修改代码后AC!详看代码。
def threeSum(nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
n = len(nums)
results = []
#没有三元组,直接返回空
if n < 3:
return results
nums.sort()
index = 0
#保证至少有三个数字参与比较,遍历列表
while index < n - 2:
#由于有序,第一个数字大于0就没必要继续找后续的两个数字。
if nums[index] > 0:
break
#left指向index索引的下一个位置,right指向最后一个位置,寻找和为0的三元组
left = index + 1
right = n - 1
while left < right:
a = nums[index]
b = nums[left]
c = nums[right]
_tmp = a + b + c
if _tmp == 0:
#这里主要是没有加入跳过重复项的思想时为了防止结果集中出现重复加入的判断,加入跳过重复项后忘记删掉,结果超时。。。
# 经过测试加入下面语句时间是4.67S,去掉是1.39S
# 下面语句用于判断结果集中是否存在重复的。
# result = [a, b, c]
# if result not in results:
# results.append(result)
now = nums[left]
# 防止left,right移动后数字值不变,判断相同则跳过
while left < right and nums[left] == now:
left += 1
now = nums[right]
while left < right and nums[right] == now:
right -= 1
elif _tmp < 0:
left += 1
elif _tmp > 0:
right -= 1
#同理,跳过重复
now = nums[index]
while index < n - 2 and nums[index] == now:
index += 1
return results
浙公网安备 33010602011771号