7.18 位运算 03

86 阅读1分钟

1 . 数组中数字出现的次数

[](剑指 Offer 56 - I. 数组中数字出现的次数 - 力扣(LeetCode))

0475.png

注意 : 相同的数字求异或为 0 ,不同的数字求异或 ,数字不同对应的比特位上为 1 ,其余为 0 。

  • 先遍历整个数组 ,对数组中的所有元素求异或 ,找到出现次数为 1 的两个数字 ,数字不同的比特位 ,结果中 ,比特位为 1 的位置 ,就是出现次数为 1 的两个数字对应比特位上数字不同的位置 。
  • 找到结果中从右数第一个比特位为 1 的位置 。
  • 通过与 1 按位与 & ,如果结果为 0 ,就把 1 向左移位 。直到找到 1 的位置 ,此时左移的结果中 , 1 所在的位置就是所求的位置 。
  • 两个不同的数字 和 左移的结果求按位与 & ,结果一个为 0 ,一个为 1 ,可通过 if 判断(和 1 求按位与 &) ,将这两个不同的数字分开 ,分到 a ,b 两个数组 ,剩下的相同的数字会被分到同一组 。在每组中 ,对所有元素求异或 ,因为相同的数字在同一组 ,而相同的数字求异或结果为 0 ,而 0 跟 任意数字求异或,结果为那个数字 。所以结果就是 那两个不同的数字 。
var singleNumbers = function(nums) {
    var diff = 0;
     nums.forEach(item=>{
        diff = diff^item;
     })
     let num = 1; 
     while((num&diff)===0)   // 注意要加括号!!!!
     {
         num<<=1;
     }
     let a,b;
     a = 0 , b= 0 ;
     nums.forEach(item=>{
         if(num&item)
         a = a ^ item;
         else
         b = b ^ item;
     })
     return [a,b];
};