前言
往年尝试过几次学算法,但是总是半途而废,所以开个记录帖,提醒自己要经常写,好好学习天天向上✌。
问:
- 有一个数组,这个数组中只有一个数存在奇数个,其他数都是偶数个,找出这个数
- 有一个数组,这个数组中有两个数是奇数个,其他数都是偶数个,找出这两个数
解:
- 使用异或运算,N ^ N = 0; 0 ^ N = N,偶数项异或结果为0,所以只剩最后一个奇数项的数
function findOneOdd(arr) {
let temp = 0
arr.forEach(i => temp ^= i)
return temp
}
- 按上述思路,可知最后剩下的是 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]
}