两数之和(包含变种)
此为leetcode的入门算法题,在网上看到用哈希map能优化所以来试一下...
主要思想使用map的key的特性来存储Array中的数值,map的value来存储Array的下角标(也算是反向存储了...)。创建一个空map,然后循环原数组,如果在map中找到对应的key则返回下角标或是其他操作,如果是没找到符合条件的,就set进map中,等待下一次的检测。
此算法本身性能感觉不是特别好,因为都是调用es6的 map操作方法,所以算不上O(n)的时间复杂(因为newMap.has()算是一次for了),会对其慢慢优化哈,希望大家多多斧我哈。
let twoSum = function(nums, target) {
let newMap = new Map(); // 创建哈希map
for(let i = 0 ;i < nums.length; i++) { //循环数组
if (newMap.has(target - nums[i])) { //借用map.has()方法判断是否存在符合target - nums[i]条件的的key
return [i, newMap.get(target - nums[i])] // 你的骚操作
}
newMap.set(nums[i], i); //如果没有就set进map
}
};
twoSum([1,2,5,6,7], 3);
------------------------------------------------------分割线 2019-08-07-----------------------------------------------------
今天在leetcode看到一个两数相加的变种题,提的需求是这样的:
如果看的上面的两数之和的话,估计是各位准备ctrl+c大法了,但是如果不用map该如何实现呢?
其实题目上给了升序排列数组,我们就可以利用这一个条件,来实现双指针对撞的方法。 思路就是从数组的两端(arr[0] 和 arr[arr.length - 1])开始循环求和,如果结果大于目标值则把 arr[arr.length - 1]的下角标前移,反之arr[0]下角标向后移,直到找到对应的下角标分别+1,下面是菜鸡代码演示。
let twoSum = function(nums, target) {
let start = 0; // 开始下角标
let end = nums.length - 1; // 结束下角标
while(start < end) { // 循环
let sum = nums[start] + nums[end]; // 当前求和
if (sum === target) { // 逻辑判断
return [start + 1, end + 1];
} else if (sum > target) {
end --;
continue;
} else(sum < target) {
start ++;
continue;
}
}
};
翻转整数
如图
var reverse = function(x) {
let sum = Math.abs(x).toString().split('').reverse().join('');
let newNum = sum > 0 ? Number(sum) : Number(sum) * -1
return (newNum > Math.pow(2, 31) - 1 || newNum < - Math.pow(2, 31)) ? 0 : newNum
};
在网上查了些资料,发现可以用js提供的 Math 对象来实现翻转,在此记录下。
主要是循环,每次循环先取余,用取余的方式获取整数的最后一位,再用 Math.floor(整数 / 10) 来获取最后一位之前的数字,然后根据 result * 10 累加,每次累加最后当num位数为0的时候停止,获得翻转数再判断他的正负
var reverse = function(x) {
let num = Math.abs(x);
let result = 0;
while(num != 0) {
result = result * 10 + num % 10
num = Math.floor(num / 10);
}
if (result > Math.pow(2, 31) - 1 || result < Math.pow(2, 31) * -1) {
result = 0;
}
return x > 0 ? result : result * -1;
};
};