算法学习记录(一)

180 阅读1分钟

前言

往年尝试过几次学算法,但是总是半途而废,所以开个记录帖,提醒自己要经常写,好好学习天天向上✌。

问:

  1. 有一个数组,这个数组中只有一个数存在奇数个,其他数都是偶数个,找出这个数
  2. 有一个数组,这个数组中有两个数是奇数个,其他数都是偶数个,找出这两个数

解:

  1. 使用异或运算,N ^ N = 0; 0 ^ N = N,偶数项异或结果为0,所以只剩最后一个奇数项的数
function findOneOdd(arr) {
    let temp = 0
    arr.forEach(i => temp ^= i)
    return temp
}
  1. 按上述思路,可知最后剩下的是 temp = a ^ b, a,b不相等,所以temp不为0,由此可推断出temp的二进制中,必定至少存在一个1,我们假设它在X位上。也就是说 a 和 b的二进制在X位上必定不相等(异或操作相同为0,不同为1)。那么,只要我们以X位的数作为分界,把数组分为两份,可知道a,b必定在不同区域。那么我们再设置一个变量temp2去异或其中的一份数组,可以得到temp2就是a或者b。最后用tmep ^ temp2,其结果就是另外一个数
function findTwoOdd(arr) {
    let temp = 0
    arr.forEach(i => temp ^= i)
    // temp = x ^ y
    // temp !== 0
    // temp 存在至少一个等于1的二进制数
    // 取二进制最右边即X位上的1
    const rightOne = temp & (~temp + 1)
    let temp2 = 0
    arr.forEach((i) => {
        // X位作为分界线
        if ((i & rightOne) === 0) {
            temp2 ^= i
        }
    })
    return [temp2, temp ^ temp2]
}