题目
给定一个整数数组nums和一个目标值target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例1:
输入: nums = [2,7,11,15], target = 9
输出: [0,1]
解释: 因为 nums[0] + nums[1] == 9, 所以返回 [0, 1].
示例2:
输入: nums = [3,2,4], target = 6
输出: [1,2]
示例3:
输入: nums = [3,3], target = 6
输出: [0,1]
解法1:两层循环
-
思路
- 找到第一个可用值a
- 从后面找和为目标值的数b
- 如果没找到,那么重新找a,直到成功
-
时间复杂度:O(n^2)
-
代码:
function twoSum(nums: number[], target: number): number[] {
let a, b;
for(let i = 0; i< nums.length - 1; i++) {
// 找到一个a
if(a == null) a = i;
// 找b
for(let j = a + 1; j < nums.length; j++) {
if(nums[i] + nums[j] === target) {
b = j;
break;
}
}
// 找到退出,没找到继续
if(b != null) break;
else a = null;
}
return [a, b];
};
- 讨论
写得有点啰嗦,可以简化点:
function twoSum(nums: number[], target: number): number[] {
for(let i = 0; i< nums.length - 1; i++) {
for(let j = i + 1; j < nums.length; j++) {
if(nums[i] + nums[j] === target) {
return [i, j]
}
}
}
return null;
};
解法2:Map缓存索引
-
思路
- 先构建一个map
- 再遍历数组
- 计算差并在map中找是否存在
-
时间复杂度:O(2n)
-
代码
function twoSum(nums: number[], target: number): number[] {
// 先构建一个map
// 再遍历数组
// 计算差并在map中找是否存在
const map = new Map(nums.map((d, i) => [d, i]));
for(let i = 0; i < nums.length; i++) {
const j = map.get(target - nums[i]);
if(j != null && j !== i) return [i, j]
}
return null;
};
改进下:map在遍历的时候赋值,后面的元素查找之前的元素,就不会重复,性能也会好点O(n)。
function twoSum(nums: number[], target: number): number[] {
// 先构建一个map
// 遍历数组时初始化,计算差并在map中找是否存在
const map = new Map();
for(let i = 0; i < nums.length; i++) {
const j = map.get(target - nums[i]);
if(j != null) return [i, j]
else map.set(nums[i], i);
}
return null;
};
- 讨论
用对象会不会好点,对象比map速度慢了,内存小了。综合来看最好。
function twoSum(nums: number[], target: number): number[] {
// 先构建一个map
// 遍历数组时初始化,计算差并在map中找是否存在
const map = {};
for(let i = 0; i < nums.length; i++) {
const j = map[target - nums[i]];
if(j != null) return [i, j]
else map[nums[i]] = i;
}
return null;
};