开始学习算法,到leetcode上找题目练手,第一题就是两数之和,难度标注为简单,想了一段时间才想出来,差点以为脑子太久没用秀逗了,之后继续做三数之和,没能全靠自己想出来,还是参考了一下别人的想法。
三数之和代码
三数之和参考了这里:https://www.jianshu.com/p/19b0261c73b9,不知道是不是编程语言的差别,如果按原思路走会超出时间限制,所以代码思路改了几个地方。
总体思路,为避免遗漏需要遍历每个数字,为避免重复,按顺序往后挑选。
class Solution:
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
count = len(nums)
collect = []
for i in range(count):
left = i+1
right = count-1
#避免重复找同一个数据
if i >0 and nums[i] == nums[i-1]:
left +=1
continue
#数据按小到大排列,每次选取nums[i],在其后寻找符合a + b + c = 0的两个数据
while left < right:
sum = nums[i] + nums[left] + nums[right]
if sum == 0:
col = [nums[i],nums[left],nums[right]]
collect.append(col)
left+=1
right-=1
#循环中nums[i]已确定,当再确定1个数时,另一个数也确定,左右端任一端出现重复均可跳过
while nums[left] == nums[left-1] and left < right:
left+=1
while nums[right] == nums[right+1] and left < right:
right-=1
if sum<0:
left+=1
elif sum > 0:
right-=1
return collect
两数之和代码
排好顺序之后,根据大小关系,缩进数字左右端范围,然后再从原始数据的副本里寻找数字对应序号。
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
nums_copy = nums.copy()
nums.sort()
front = 0
end = len(nums) - 1
while end>front:
if nums[front]+nums[end]>target:
end -=1
elif nums[front]+nums[end]
front+=1
else:
first = nums_copy.index(nums[front])
#如果first和second相等,可能会找到同一个序号,所以设置为None
nums_copy[first] = None
second = nums_copy.index(nums[end])
return first,second
leetcode里两数之和耗时最短的代码利用差值和字典,思维简洁而精确;三数之和耗时最短的代码利用了除0以外正负数相加才会等于零的关系,划分正负数,按条件选取;用好数学关系确实能使代码高效不少。