题目

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

示例 1:

输入:nums = [4,1,4,6]

输出:[1,6] 或 [6,1]

示例 2:

输入:nums = [1,2,10,4,1,4,3,3]

输出:[2,10] 或 [10,2]

限制:

2 <= nums <= 10000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof

思路

  • 通过异或消除重复出现的数字
  • 找出 a ^ b 中值为1的位,在该位上,a和b的值一定 不相等 。通过该位就可以分离a和b了

    代码

    1. class Solution {
    2. public int[] singleNumbers(int[] nums) {
    3. // 设所有数字的异或结果为k
    4. int k = 0;
    5. // 计算异或结果
    6. for (int num : nums) {
    7. k ^= num;
    8. }
    9. // 设出现一次的两个数字是a, b
    10. // k = a ^ b
    11. // 设a, b最低差异位的掩码位mask
    12. int mask = 1;
    13. // 找到最低差异位的掩码
    14. while ((k & mask) == 0) {
    15. mask <<= 1;
    16. }
    17. // 已经找到a, b的最低差异位
    18. // 根据该位的值将数据分为两组进行异或运算
    19. // a, b被分开,重复数字被异或清0掉,最后就剩下了a, b两个数字
    20. int a = 0, b = 0;
    21. for (int num : nums) {
    22. if ((num & mask) == 0) {
    23. a ^= num;
    24. } else {
    25. b ^= num;
    26. }
    27. }
    28. return new int[]{a, b};
    29. }
    30. }