剑指offer 2.21

98 阅读1分钟

剑指 Offer 56 - I. 数组中数字出现的次数

var singleNumbers = function(nums) {
    let res = 0;
    for(let i of nums){
        res ^= i;
    }
    let diff = 1;
    while(!(diff&res)){//注意优先级,!大于&,这里要加括号。
        diff <<= 1;
    }
    console.log(diff)
    let a = 0;
    let b = 0;
    for(let i of nums){
        if(diff&i) a^=i;
        else b^=i;
    }
    return [a,b];
};

剑指 Offer 56 - II. 数组中数字出现的次数 II

// 低质量哈希
var singleNumber = function(nums) {
    let map = new Map();
    for(let i of nums){
        if(map.has(i)) map.set(i,true);
        else map.set(i, false);
    }
    for(let i of nums){
        if(map.get(i)) continue;
        else return i;
    }
};

剑指 Offer 66. 构建乘积数组

var constructArr = function(a) {
    let left = new Array(a.length);
    let right = new Array(a.length);
    let res = new Array(a.length);
    left[0] = 1;
    right[a.length-1] = 1;
    for(let i = 1;i<a.length;i++){
        left[i] = i==1?a[0]:a[i-1]*left[i-1];
    }
    for(let i = a.length-2;i>=0;i--){
        right[i] = i==a.length-2?a[a.length-1]:a[i+1]*right[i+1];
        res[i] = left[i]*right[i];
    }
    res[a.length-1] = left[a.length-1];
    return res;
};

剑指 Offer 14- I. 剪绳子

// 数学规律题,切分为3时最大,不能为3就乘2,为1则拆3补2*2(4>3)。
var cuttingRope = function(n) {
    if(n<=3) return n-1;
    let rest = n%3;
    let count = Math.floor(n/3);
    let res = 1;
    if(rest==1){
        count--;
        res *= 2*2;
    }
    else if(rest==2){
        res *= 2;
    }
    while(count--){
        res *= 3;
    }
    return res;
};

剑指 Offer 62. 圆圈中最后剩下的数字

// 理解约瑟夫环的解法(链表超时..)
var lastRemaining = function (n, m) {
    if(n==1) return 0;
    return (lastRemaining(n-1,m)+m)%n;
};

关于约瑟夫环的解法。

将数组无限后移,每一个新的起始下标,都是基于前面的数组后移实现的,若还原到原本的数组则下标需要加m,由于最后只剩一个人,所以的下标为0,每一个新的起始点都对应一个数字的删除,总数会减一。