- 题目来源: https://leetcode.com/problems/two-sum/description/
- 题目: Two Sum
- 题目描述:
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].
具体我再描述一下这一题的意思就是,给一个目标整数以及一个目标整数数组,然后这个整数数组里面的某两个数加起来等于这个目标整数,然后返回这两个整数在数组里面的下标。
来马上看一看我写出来的算法:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
if(!Array.isArray(nums)) return false;
if(isNaN(parseFloat(target))) return false;
var i, j;
for(i = 0;i < nums.length; i++) {
for(j = i + 1; j < nums.length; j++) {
if(nums[i] + nums[j] === parseFloat(target)) {
return [i, j];
}
}
}
return [-1, -1];
};
我的思路当然是先检查一下传进来的参数是不是对的,增加一下方法的严谨性,这是弱类型语言应该去做的一些事情。然后开始求解,我的思路很简单,就是两层循环,题目说了有且只有唯一解,那我只要找到唯一解就return即可。讲道理非常简单暴力,可能是没学过算法又或者说没有考虑那么多东西,有时候实用为主,但是我从一开始就认为我的答案就肯定不是最优解,然后想了一想最优解,但是人总是容易被自己的思维所限,然后我去找了其他人的高分答案,我发现了他们用map,js里面就是用对象来处理这个方法,来下面我贴一段别人的解法(侵删)这是引用地址:
var twoSum = function(nums, target) {
var ret = [];
var exist = {};
for(var i = 0; i < nums.length; i++){
if(typeof(exist[target - nums[i]]) !== 'undefined'){
ret.push(exist[target - nums[i]]);
ret.push(i + 1);
}
exist[nums[i]] = i + 1;
}
return ret
};
然后仔细读了两遍这个代码并仔细计算过后发现,答案好像根本不对,然后发现它好像每次都多加了一个1,但是思路是没有问题的,然后我改成了这样:
var twoSum = function(nums, target) {
var ret = [];
var exist = {};
for(var i = 0; i < nums.length; i++){
if(typeof(exist[target - nums[i]]) !== 'undefined'){
ret.push(exist[target - nums[i]]);
ret.push(i);
}
exist[nums[i]] = i;
}
return ret
};
这位作者的原来所能够想到的方法更好,起码它这里只用了一次循环,算法复杂度上比我少了一个平方,这个肯定是更优解。理一下他的思路,他是准备一个数组,准备一个对象,然后开始循环传递进来的数组,用目标整数去减循环到的当前整数,如果正好在对象里面有匹配的键名说明这个数是对的,就把那个目标在之前存进去的下标给push到准备好的空数组里面,如果没有匹配或者匹配到的值是undefined,就把当前循环的整数值存到对象中去,用当前整数当键名,用他的下标当键值。
所以这一道算法题就到这里,我讲明白了么?