Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
分析
该问题有两种解法:
- 构造一个字典,遍历nums,以nums的元素为键,以元素的下标为值,填充到字典中。然后遍历nums,对每个元素x,在字典中查找键target - x是否存在。如果target - x是字典的键, 找到字典中键target - x 对应的值, 即target - x的下标,如果该下标不等于x的下标,那么我们就找到了两个相加之和等于target的数组元素。时间复杂度为, 空间复杂度为O(n), 这是一种空间换时间的策略。要注意的是,假如nums有几个相等的元素,字典却只记录了一个下标,丢失了其他下标的信息,所以这种解法不能用来找全部解。
- 对nums进行升序排列。考察value = nums[1] + nums[n], 如果value == target, 我们找到了解,如果value < target,第一个元素和任何元素的和都小于target,这样我们就排除了第一个元素,问题的解只能在子列nums[2...n]中;同理如果value > target,最后一个元素和任何元素的和都大于target,这样我们就排除了最后一个元素,问题的解只能在子列nums[1...n-1]中。这样,我们或者能找到解,或者把问题转化为数组长度减少的子问题, 直到数组长度减到零。该解法时间复杂度和空间复杂度由排序算法决定。
伪代码
twoSum(nums, target)
Initialize map m
n = nums.length
for i = 1 to n
m[nums[i]] = i
for i = 1 to n
value = target - nums[i]
if value in m and m[value] != i
return [i, m[value]]
return null
twoSum(nums, target)
sort nums by ascending order
left = 0
right = nums.length
while left < right
value = nums[left] + nums[right]
if value == target
return [left, right]
elseif value < target
left += 1
else
right -= 1
return null