问题描述
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
解题思路
常规做法遍历所有情况直到满足条件。
| class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
n = len(nums)
for i in range(n):
for j in range(i + 1, n):
if nums[i] + nums[j] == target:
return [i, j]
return []
|
然后就超时了,这说明 \(\mathcal{O}(n^2)\) 的复杂度过不了。
一种解决方法是,我们先对数据进行排序,同时要保留数据原始的下标,然后使用类似二分法的过程来求解。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
p = [(i, x) for i, x in enumerate(nums)]
p.sort(key=lambda x: x[1])
lo, hi = 0, len(nums) - 1
while lo < hi:
t = p[lo][1] + p[hi][1]
if t == target:
# return sorted([p[lo][0], p[hi][0]])
return [p[lo][0], p[hi][0]] # 答案与下标顺序无关
elif t < target:
lo += 1
else:
hi -= 1
return []
|
另一种方法就是使用一个字典来保留已经遇到的数字及其下标。
| class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
m = {}
for i, x in enumerate(nums):
res = target - x
if res in m:
return [m[res], i]
m[x] = i
return []
|