暴力法,时间复杂度O(n*n),空间复杂度O(1)
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(nums)):
for j in range(i+1, len(nums)):
if nums[i] + nums[j] == target:
return [i, j]
hashmap,时间复杂度O(n),空间复杂度O(n)
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
hashmap = {}
for index, num in enumerate(nums):
res = target - num
if res in hashmap:
return [hashmap[res], index]
hashmap[num] = index
二分查找,先排序,后双指针,排序时间复杂度为O(nlog(n)),双指针时间复杂度为O(n)
所以,总的时间复杂度为O(nlog(n))
该方法返回的是对应的数字,而不是数字索引,要想知道索引,需要保存原数组进行二次查找。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
nums = sorted(nums)
n = len(nums)
left = 0
right = n - 1
while left < right:
s = nums[left] + nums[right]
if s == target:
return [nums[left], nums[right])]
elif s < target:
left += 1
elif s > target:
right -= 1
如果数组有重复数,并且存在多对数字和为target,代码如下
def twoSum(nums, target):
nums.sort()
n = len(nums)
left = 0
right = n - 1
res = []
while left < right:
s = nums[left] + nums[right]
lo = nums[left], hi = nums[right]
if s < target:
while left < right and nums[left] == lo:
left += 1
elif s > target:
while left < right and nums[right] == hi:
right -= 1
else:
res.append([lo, hi])
while left < right and nums[left] == lo:
left += 1
while left < right and nums[right] == hi:
right -= 1
return res
外层for循环遍历每一个数,内层变为求两数之和为target-nums[i]
排序时间复杂度为O(nlog(n)),外层for循环复杂度为O(n),双指针时间复杂度为O(n)
时间复杂度O(nlog(n) + nn)=O(nn)
注意跳过重复数
def threeSum(nums, target):
nums.sort()
n = len(nums)
res = []
i = 0
while i < n:
tuples = twoSum(nums, i + 1, target - nums[i])
if not tuples:
i += 1
continue
for t in tuples:
res.append(t)
i += 1
while i < n and nums[i] == nums[i - 1]:
i += 1
return res
def twoSum(nums, start, target):
left = start
right = len(nums) - 1
res = []
while left < right:
...(两数之和代码)
return res
外层for循环遍历每一个数,内层变为求三数之和为target-nums[i]
请读者自行发挥。
def nSum(nums, n, start, target):
size = len(nums)
res = []
# 至少是2 sum, 并且数组大小不应该小于n
if n < 2 or size < n:
return res
if n == 2:
left = start
right = size - 1
while left < right:
s = nums[left] + nums[right]
lo = nums[left]
hi = nums[right]
if s < target:
while left < right and nums[left] == lo:
left += 1
elif s > target:
while left < right and nums[right] == hi:
right -= 1
else:
res.append([lo, hi])
while left < right and nums[left] == lo:
left += 1
while left < right and nums[right] == hi:
right -= 1
else:
# n > 2时,递归计算(n-1)sum的结果
i = start
while i < size:
sub = nSum(nums, n - 1, i + 1, target - nums[i])
# (n - 1) sum + nums[i]就是n sum
for arr in sub:
arr.append(nums[i])
res.append(arr)
i += 1
while i < size and nums[i] = nums[i - 1]:
i += 1
return res