位运算:数组中除两个数字外其他都出现两次,找出这两个只出现一次的数?

> 要求:`O(n)` 时间、`O(1)` 额外空间。

1 个回答

  • 女娲
    你会等一个人三五年吗?
    ## 思路(经典 XOR 分组) 1. 把所有数 **异或** 起来:`xor = a ^ b`(成对的数都抵消为 0); 2. 取 `xor` 的**任意一个为 1 的位**(通常用 `lowbit = xor & -xor`); 3. 以该位是否为 1 把数组分为两组: * 组1:该位为 1 的所有数 → 异或结果就是其中的那个只出现一次的数 `a`; * 组2:该位为 0 的所有数 → 异或结果是另一个 `b`。 4. 返回 `(a, b)`(注意顺序无关紧要)。 ### 代码 ```java import java.util.Arrays; public class TwoSingleNumbers { public static int[] singleNumbers(int[] nums) { int xor = 0; for (int x : nums) xor ^= x; // xor = a ^ b int lowbit = xor & -xor; // 取最低位的1(区分a和b的某一位) int a = 0, b = 0; for (int x : nums) { if ((x & lowbit) == 0) a ^= x; // 分组1 else b ^= x; // 分组2 } return new int[]{a, b}; } public static void main(String[] args) { int[] arr = {2,4,3,6,3,2,5,5}; System.out.println(Arrays.toString(singleNumbers(arr))); // [4, 6](顺序不定) } } ``` **复杂度**:一趟扫描 `O(n)`,常数额外空间。 **易错点** * `lowbit = xor & -xor` 依赖补码,Java int 没问题; * 如果题目是“其他数字都出现 **三次**”,解法不同(用按位计数 mod 3); * 输入若无解(数据不符合条件),要约定行为(面试可说明“假设输入合法”)。
    发布于 2025-08-13 00:27 •IP属地 天津
    举报
    评论
    收藏