问题描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
接着,给出我自己的方法:
/* javascript编写 */
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
function twoSum (nums, target) {
// 这里的作用是开辟一块新的内存复制nums数组
let temp = nums.slice(0)
// 对temp数组进行排序
temp.sort(function (a, b) {
return a - b
})
let i = 0, j = nums.length - 1
let tempSum = temp[i] + temp[j]
while (tempSum !== target) {
// 如果首尾相加大于目标值,则j要减1
if (tempSum > target) j--
// 如果首尾相加小于目标值,则i要加1
else i++
// 出现i > j的情况则说明数组中不存在这样的两个数
if (i > j) throw "no two sum solution"
// 正常情况下我们要先计算下依次下标i,j对应数的和
else tempSum = temp[i] + temp[j]
}
// 到这一步,就说明存在这样的两个数,那么我们将这两个数在原来的数组中寻找到它们的下标
let a, b
for (let n = 0; n < nums.length; n++) {
if (a === undefined && nums[n] === temp[i]) a = n
if (a !== n && b === undefined && nums[n] === temp[j]) b = n
if (a !== undefined && b !== undefined) break
}
return [a, b]
}
时间复杂度分析:从上面的代码中可以看到,我们先将数组进行排序,然后进行了一个while循环(O(n)),最后又进行了一次for循环(O(n)),所以起绝对作用的是数组排序的时间复杂度(八大排序算法之一)。
官方解答:
解法一:
/* 方法一,暴力法 */
/* javascript编写 */
/*
复杂度分析:
1.时间复杂度:O(n^2),对于每个元素,我们试图通过遍历数组的其余部分来寻找它所对应的目标元素,这将耗费O(n)的时间。因此时间复杂度为O(n^2).
2.空间复杂度:O(1).
*/
function twoSum (nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[j] === target - nums[i]) {
return [i, j]
}
}
}
throw "no two sum solution"
}
解法二:
/* java编写 */
/* 方法二:两遍哈希表 */
/*
复杂度分析:
1.时间复杂度:O(n), 我们把包含有 n 个元素的列表遍历两次。由于哈希表将查找时间缩短到 O(1) ,所以时间复杂度为 O(n)。
2.空间复杂度:O(n), 所需的额外空间取决于哈希表中存储的元素数量,该表中存储了 n 个元素。
*/
public int[] twoSum(int[] nums, int target) {
Map < Integer, Integer > map = new HashMap < > ();
for (int i = 0; i < nums.length; i++) {
map.push(nums[i], i);
}
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement) && map.get(complement) != i) {
return new int[] {
i,
map.get(complement)
}
}
}
throw new IllegalArgumentException("No two sum solution")
}
解法三:
/* javascript编写,这里用对象来代替哈希表 */
/*
复杂度分析:
1.时间复杂度:O(n), 我们只遍历了包含有 n 个元素的列表一次。在表中进行的每次查找只花费 O(1)的时间。
2.空间复杂度:O(n), 所需的额外空间取决于哈希表中存储的元素数量,该表最多需要存储 n 个元素。
*/
/* 方法三:一遍哈希表 */
function twoSum(nums, target) {
let arrObj = {}
for (let i = 0; i < nums.length; i++) {
let complement = target - nums[i]
if (undefined !== arrObj[complement]) {
return [arrObj[complement], i]
}
arrObj[nums[i]] = i
}
throw "no two sum solution"
}