菜鸡前端刷leetcode算法题

243 阅读3分钟

两数之和(包含变种)

此为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;
            }
        }
    };

还有个问题就是leetcode的代码测试反馈有的时候不太准确,我看不到测试用例,我猜可能是每次的测试用例不一样产生的,leetcode我用的不太熟,如果有骚操作请务必通知我哈,本人也会持续更新自己的刷题经验,谢谢观看。

翻转整数

如图

接下来是我的代码,主要考察的是数组,字符串的api运用,注意下边界问题处理就好了。

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;
};
};