1.两数之和LeetCode(js)
题目说明:
题解:
方法一:暴力枚举法(双重for循环)
解题思路
- 枚举数组中的每一个数 x,寻找数组中是否存在 target - x。
- 使用双重for循环,外层for循环从索引 [i] 开始,内层for循环从索引 [i+1] 开始,找到数组中存在两个元素之和等于目标元素时,返回两个元素的索引值。
- 当我们使用遍历整个数组的方式寻找 target - x(加法转化为减法) 时,需要注意到每一个位于 x 之前的元素都已经和 x 匹配过,因此不需要再进行匹配。而每一个元素不能被使用两次,所以我们只需要在 x 后面的元素中寻找 target - x。
代码:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
//判断数组是否为空或长度小于2
if(nums.length < 2){
return [];
}
for(let i = 0; i <nums.length; i++){
//j = i + 1 的目的是减少重复计算和避免两个元素下标相同
for(j = i+1; j <nums.length; j++){
if(nums[i] + nums[j] == target){
return[i,j];
}
}
}
//没有找到匹配的两个数,也要返回一个空列表,用来表示无答案
return[];
}
时间复杂度:O(N²) ,其中 N是数组中的元素数量。最坏情况下数组中任意两个数都要被匹配一次,时间复杂度较高。
空间复杂度:O(1)
方法二: 哈希表
解题思路:
- 创建一个map
- for循环遍历nums数组
- 遍历的同时,记录一些信息,省去一层循环,以空间换时间,
需要记录已经遍历过的数值和它对应的下标,借助查表 - 检查map里是否有值x,使得 x= ( target - nums[i] )
- 如果有则返回 x 和 nums[i] 的数组下标,作为答案
- 如果没有,把nums[i]当作key, i 当作value存入map中
注意:
- map对象中存放的是{key,value}键值对
- has(key)方法判断map中是否存在key,返回boolen值
has方法是依据key来判断的,所以值放在key,索引放在value - get(key)方法返回map中的value值
- set(key,value)方法为Map对象添加一个指定键和值的元素
代码:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
//创建map
let map = new Map;
for(let i = 0; i < nums.length; i++){
x = target - nums[i];
//是否存在x
if(map.has(x)){
//返回索引
return [map.get(x),i];
}
// 不存在nums[i] + x = target,把nums[i]保存到map中
map.set(nums[i],i);
}
//没有答案,返回空列表
return [];
}
时间复杂度:O(N),其中 NN是数组中的元素数量。对于每一个元素 x,我们可以 O(1)地寻找 target - x。
空间复杂度:O(N),其中 N 是数组中的元素数量,主要为哈希表的开销。