算法及思路(二)

1.三数之和 -- 哈希表思想

ps:判断数组元素是否相同时先转换为字符串再进行比较

思路1: 拉到两人后登记在册找符合要求的第三人(会有重复的组合)
    // 双重循环,保存已有的两个数为数组[-1,0],寻找符合条件的第三个数
    // 用哈希表存储,key为符合的值,value为已存在的两值的数组
    // 如当前循环中 i==-1, j==0;则obj [1] == [-1,0]
    // 当内循环的值在哈希表中有对应的值时,说明内循环当前的值是符合要求的值

var threeSum = function (nums) {
    var reArr = [];
    var obj = {};
    if (nums.length > 3) {
        for (let i = 0; i < nums.length - 2; i++) {
            for (let j = i + 1; j < nums.length - 1; j++) {
                if (obj[nums[j]] == undefined) {
                    var mark = 0 - nums[i] - nums[j];
                    obj[mark] = [nums[i], nums[j]];
                } else {
                    reArr.push((obj[nums[j]].concat([nums[j]])).sort());
                    obj[nums[j]] = undefined;
                }
            }
        }
    } else if (nums.length == 3) {
        var cont = 0;
        nums.forEach(ele => {
            cont += ele
        });
    } else {
        return []
    }
    if (cont == 0) {
        return nums
    }
}

 改进:   

    // 先排序,后选一个在中间,左右各一个元素
    // 如果三数之和大于0,说明右侧元素太大,右侧左移一位,小于0左侧右移一位
    // 要移动的元素在自己边上 -- 移动的下一位为自己时结束循环,
    // 下一个中间的元素如果与上一个相同则跳过

var threeSum = function (nums) {
    var reArr = [];
    var sum;
    nums = nums.sort(function (a, b) {
        return a - b
    })
    for (let i = 1; i < nums.length; i++) {
        var l = 0;
        var r = nums.length - 1;
        sum = nums[i] + nums[l] + nums[r]
        log("新一轮")
        // if(nums[i] == nums[i-1]) break
        while (l != i && r != i) {
            log(l, i, r)
            // log(nums[l],nums[i],nums[r])
            if (sum > 0) {
                r -= 1;
                // if(r <= i) break
                sum = nums[i] + nums[l] + nums[r]
            } else if (sum < 0) {
                l += 1;
                // if(l >= i) break
                sum = nums[i] + nums[l] + nums[r]
            } else {
                // 相同
                log("相同", l, i, r)
                // if(l >= i || r <= i) break
                reArr.push([nums[l], nums[i], nums[r]]);
                l += 1;
                r -= 1;
            }
        }
        if (nums[i] == nums[i - 1]) {
            continue
        }
    }
    return reArr;
}

2.数组相加 -- 进位 -- 2019/7/27

function SUM(one, two) {
    var newArr = [];
    var i = 0;
    var tim = 0;
    var flag = true;
    while (flag || tim) {
        // 计算每一位加进位的结果,判断是否大于10
        // 大于10取余, 进位为1, 小于10直接相加,进位为0
        // 只要有一个数组有值就继续
        if (one[i+1] === undefined && two[i+1] === undefined) {
            flag = false;
        }
            one[i] = one[i] ? one[i] : 0;
            two[i] = two[i] ? two[i] : 0;
        if (one[i] + two[i] + tim >= 10) {
            newArr[i] = (one[i] + two[i] + tim) % 10;
            tim = 1;
        } else {
            newArr[i] = one[i] + two[i] + tim;
            tim = 0;
        }
        // log(newArr,flag,tim)

        i++;
    }
    return newArr;
}

3.递归生成不重复的拥有5个成员的数组 -- 2019/8/8

题目:1.生成一个拥有5个成员的数组

           2.生成(0-32]之间的随机数

           3.将随机数插入数组,保证数组成员不重复

let arr = new Array(5);
let i = 0;
let setArr = function(x) {
    let rand = parseInt(Math.random() * 30 + 2);
    while(x === rand) {
        rand = parseInt(Math.random() * 30 + 2);
    }
    if(arr[arr.length-1]) {
        return arr;
    }
    arr[i++] = rand;
    return setArr(rand);
}

 改进版:不使用while,上面方法可能会有重复

let arr = new Array(5);
let i = 0;
let rand = parseInt(Math.random() * 30 + 2);
let setArr = function (x) {
    if (arr[arr.length - 1]) {
        return arr;
    };
    if(arr.includes(x)) {
        rand = parseInt(Math.random() * 30 + 2);
    }else {
        arr[i++] = rand
    }
    setArr(rand);
    return arr;
}

题目源自:前端面试每日 3+1(每日三问)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值