两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
暴力解法(线性查找):
执行用时: 4624 ms
内存消耗: 13.6 MB
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(len(nums)):
if j == i:
continue
elif nums[j] + nums[i] == target:
return i, j
线性查找的优化:
执行用时: 436 ms
内存消耗: 13.6 MB
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(nums)):
j = target - nums[i]
if j in nums and nums.index(j) != i:
return i, nums.index(j)
哈希查找:
执行用时: 24 ms
内存消耗: 13.7 MB
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
d = {x: i for i, x in enumerate(nums)}
for i in range(len(nums)):
n = target - nums[i]
if n in d and d.get(n) != i:
return i, d.get(n)
两数之和——有序数组
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
二分查找:
执行用时: 84 ms
内存消耗: 13.8 MB
class Solution(object):
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(numbers)):
x = numbers[i]
index = self.binary_search(numbers, i+1, len(numbers)-1, target-x)
if index != -1:
return [i+1, index+1]
return []
def binary_search(self, numbers, left, right, target):
while left <= right:
mid = left + (right - left) // 2
if target == numbers[mid]:
return mid
elif target > numbers[mid]:
left = mid + 1
else:
right = mid - 1
return -1
哈希查找:
执行用时: 24 ms
内存消耗: 13.9 MB
class Solution(object):
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
d = {x: i for i, x in enumerate(numbers)}
for i in range(len(numbers)):
n = target - numbers[i]
if n in d and d.get(n) != i:
return [i+1, d.get(n)+1]
return []
双指针:
执行用时: 24 ms
内存消耗: 13.4 MB
class Solution(object):
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
left, right = 0, len(numbers)-1
while left < right:
sum = numbers[left] + numbers[right]
if sum == target:
return [left+1, right+1]
elif sum < target:
left = left + 1
else:
right = right -1
return []
三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
双指针:
执行用时: 540 ms
内存消耗: 18.5 MB
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
res, k = [], 0
for k in range(len(nums)-2):
if nums[k] > 0:
break
if k > 0 and nums[k] == nums[k-1]:
continue
i, j = k + 1, len(nums) - 1
while i < j:
s = nums[k] + nums[i] + nums[j]
if s < 0:
i += 1
while i < j and nums[i] == nums[i-1]:
i += 1
elif s > 0:
j -= 1
while i < j and nums[j] == nums[j+1]:
j -= 1
else:
res.append([nums[k], nums[i], nums[j]])
i += 1
j -= 1
while i < j and nums[i] == nums[i-1]:
i += 1
while i < j and nums[j] == nums[j+1]:
j -= 1
return res
四数之和
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且 不重复 的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
- 0 <= a, b, c, d < n
- a、b、c 和 d 互不相同
- nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
双指针:
执行用时: 684 ms
内存消耗: 13 MB
class Solution(object):
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
nums.sort()
res = []
for k in range(len(nums)):
if k > 0 and nums[k] == nums[k-1]:
continue
for l in range(k+1, len(nums)):
if l > k + 1 and nums[l] == nums[l-1]:
continue
i, j = l + 1, len(nums) - 1
while i < j:
s = nums[k] + nums[l] + nums[i] + nums[j]
if s < target:
i += 1
while i < j and nums[i] == nums[i-1]:
i += 1
elif s > target:
j -= 1
while i < j and nums[j] == nums[j+1]:
j -= 1
else:
res.append([nums[k], nums[l], nums[i], nums[j]])
i += 1
j -= 1
while i < j and nums[i] == nums[i-1]:
i += 1
while i < j and nums[j] == nums[j+1]:
j -= 1
return res