给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
方法一:暴力法 多层遍历
遍历每个元素num,并查找是否存在一个值与target - nun相等的目标元素。
var twoSum = function(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] === target) {
return [i, j]
}
}
}
return []
};
twoSum([2, 7, 11, 15], 9)
复杂度分析:
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度:
O
(
1
)
O(1)
O(1)
方法二:数组遍历1
通过空间换取时间的方式。
var twoSum = function(nums, target) {
let map = []
for (let i = 0; i < nums.length; i++) {
map.push(nums[i])
}
for (let i = 0; i < nums.length; i++) {
const twice = target - map[i]
const j = map.indexOf(twice)
if (j > -1 && i !== j) {
return [i, j]
}
}
return []
};
twoSum([2, 7, 11, 15], 9)
复杂度分析:
- 时间复杂度:
O
(
n
)
O(n)
O(n)
- 我们把包含有 n 个元素的列表遍历两次。由于数组将查找时间缩短到 O ( 1 ) O(1) O(1) ,所以时间复杂度为 O ( n ) O(n) O(n)。
- 空间复杂度:
O
(
n
)
O(n)
O(n)
- 所需的额外空间取决于数组中存储的元素数量,该表中存储了
n
n
n 个元素。
- 所需的额外空间取决于数组中存储的元素数量,该表中存储了
n
n
n 个元素。
方法三:数组遍历2
通过空间换取时间的方式。
var twoSum = function(nums, target) {
let map = []
for (let i = 0; i < nums.length; i++) {
const twice = target - nums[i]
const j = map.indexOf(twice)
if (j > -1 && i !== j) {
return [i, j]
}
map.push(nums[i])
}
return []
};
twoSum([2,7,11,15], 9)
复杂度分析:
- 时间复杂度:
O
(
n
)
O(n)
O(n)
- 我们只遍历了包含有 n 个元素的列表一次。在表中进行的每次查找只花费 O ( 1 ) O(1) O(1) 的时间。
- 空间复杂度:
O
(
n
)
O(n)
O(n)
- 所需的额外空间取决于数组中存储的元素数量,该表最多需要存储
n
n
n 个元素。
- 所需的额外空间取决于数组中存储的元素数量,该表最多需要存储
n
n
n 个元素。
方法四:双指针查找
(满足index必须小于index2,且不可重复使用相同的元素)
使用两个指针(low, high),初始位置分别为第一个元素和最后一个元素位置,比较两个元素之和sum与目标值target的大小,如果等于target值,则得到唯一解。如果比target值小,则将low的值加1;否则high加1。移动指针后重复上述操作直到找到答案或low等于high,跳出while循环。
var twoSum = function(numbers, target) {
let low = 0
let high = numbers.length - 1
while(low < high) {
const sum = numbers[low] + numbers[high]
if (sum === target) {
return [low, high]
} else if (sum > target) {
high --
} else {
low ++
}
}
};
twoSum([2, 7, 11, 15], 9)
复杂度分析:
- 时间复杂度:
O
(
n
)
O(n)
O(n)
- 每个元素只被访问一次,总共n个元素。
- 空间复杂度:
O
(
1
)
O(1)
O(1)
- 只用到两个指针。
- 只用到两个指针。
方法五:二分法查找
(满足index必须小于index2,且不可重复使用相同的元素)
const NOT_FOUND = -1
var twoSum = function(numbers, target) {
for (let i = 0; i < numbers.length; i++) {
let y = target - numbers[i]
let res = binarySearch(numbers, y)
if(res !== NOT_FOUND && i !== res){
return i < res ? [i + 1, res + 1] : [res + 1, i + 1]
}
}
}
const binarySearch = function(array, target) {
let low = 0
let high = array.length - 1
while (low <= high) {
let mid = ~~((low + high) / 2)
if (array[mid] < target) {
low = mid + 1
} else if (array[mid] > target) {
high = mid - 1
} else {
return mid
}
}
return NOT_FOUND
}
twoSum([2, 7, 11, 15], 9)