使用位运算查找只出现一次的数字

一个数组中只有一个数字出现一次,其他数字都出现两次,请找出这个数字

class Solution {

  public int singleNumber(int[] nums) {
    int res = 0;
    for (int num : nums) {
      res ^= num;
    }
    return res;
  }

  public static void main(String[] args) {
    System.out.println(new Solution().singleNumber(new int[]{2, 2, 1}));
    System.out.println(5);
  }
}

leetcode-136. 只出现一次的数字
异或运算有以下性质

a^0=a                   任何数异或0等于自身
a^a=0                   任何数和自身异或等于0
a^b^a=a^(b^a)=(a^a)^b=b 满足交换律和结合律

以数组[2,2,1]为例,1^2^1=1^1^2=0^2=2

一个数组中只有两个数字出现一次,其他所有数字都出现了两次,请找出这两个数字

import java.util.Arrays;

class Solution {

  public int[] singleNumber(int[] nums) {
    int xorRes = 0;
    for (int num : nums) {
      xorRes ^= num;
    }
    //找到第一位不为0的位数,如6 pos为1
    int pos = 0;
    while (((xorRes >> pos) & 1) == 0) {
      pos++;
    }
    //分组异或 分为pos位为0的和pos位为1的
    int res1 = 0;
    int res2 = 0;
    for (int num : nums) {
      if (((num >> pos) & 1) == 0) {
        res1 ^= num;
      } else {
        res2 ^= num;
      }
    }
    return new int[]{res1, res2};
  }

  public static void main(String[] args) {
    int[] res = new Solution().singleNumber(new int[]{1, 2, 1, 3, 2, 284593787});
    System.out.println(Arrays.toString(res));
  }
}

leetcode-260. 只出现一次的数字 III
先对所有数字进行一次异或,结果为两个出现一次数字的异或值,得到第一个为1的位的位置,根据这一位是否为1,将所有数字分成两组:

  • 两个只出现一次的数字分在不同的组中
  • 相同的数字分在相同的组中

分别对每一组进行异或即可得到答案,以数组[1,2,3,1,2,5]为例,第一次异或之后得到6,二进制表示为000...0110,第一个为1的位的位置为1,根据这一位分组。

一个数组中只有一个数字出现一次,其他数字都出现三次,请找出这个数字

class Solution {

  public int singleNumber(int[] nums) {
    int res = 0;
    for (int i = 0; i < 32; i++) {
      int bitSum = 0;
      for (int num : nums) {
        bitSum += (num >> i) & 1;
      }
      res += (bitSum % 3) << i;
    }
    return res;
  }

  public static void main(String[] args) {
    System.out.println(new Solution().singleNumber(new int[]{2, 2, 3, 5, 3, 3, 2}));
  }
}

leetcode-137. 只出现一次的数字 II
对所有数字,统计每一位的个数,对3取模,以数组[2,2,2,5]为例,统计得到第0位个数1,第1位个数3,第二位个数1,转成十进制为

1<<2 + 0<<0 + 1<<1 = 5
posted @ 2021-06-17 00:06  strongmore  阅读(122)  评论(0编辑  收藏  举报