当前位置: 面试刷题>> 不重复的两个数 (经典算法题500道)


题目描述补充

题目:在一个整数数组中,除了两个数字之外,其他数字都出现了两次。请找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度尽量低。

示例

给定数组 [1, 2, 3, 2, 3, 4, 5],输出应为 [1, 4, 5] 中的任意两个数(因为 4 和 5 是只出现一次的数字,但题目只要求找出两个即可,不特定顺序)。但为简化问题,我们常约定以某种方式(如异或结果的性质)区分并返回这两个数。

解题思路

利用异或(XOR)运算的性质:任何数和0做异或运算,结果仍然是原来的数;任何数和其自身做异或运算,结果是0;异或运算满足交换律和结合律。

  1. 首先,将所有数字进行异或运算,得到的结果是两个只出现一次的数字的异或结果。
  2. 然后,找到异或结果中任意一个为1的位,这个位在两个只出现一次的数字中必为一个为0,一个为1。
  3. 接下来,根据这个位将数组分为两组,一组是该位为0的所有数字,另一组是该位为1的所有数字。
  4. 最后,分别对两组中的所有数字进行异或运算,得到的结果就是两个只出现一次的数字。

PHP 代码示例

function findTwoUniqueNumbers($nums) {
    $xor = 0;
    foreach ($nums as $num) {
        $xor ^= $num;
    }

    // 找到xor中任意一个为1的位
    $bit = 1;
    while (($bit & $xor) == 0) {
        $bit <<= 1;
    }

    $a = $b = 0;
    foreach ($nums as $num) {
        if (($num & $bit) != 0) {
            $a ^= $num;
        } else {
            $b ^= $num;
        }
    }

    return [$a, $b];
}

// 示例
$nums = [1, 2, 3, 2, 3, 4, 5];
$result = findTwoUniqueNumbers($nums);
print_r($result);

Python 代码示例

def find_two_unique_numbers(nums):
    xor = 0
    for num in nums:
        xor ^= num

    # 找到xor中任意一个为1的位
    bit = 1
    while (bit & xor) == 0:
        bit <<= 1

    a, b = 0, 0
    for num in nums:
        if num & bit:
            a ^= num
        else:
            b ^= num

    return [a, b]

# 示例
nums = [1, 2, 3, 2, 3, 4, 5]
result = find_two_unique_numbers(nums)
print(result)

JavaScript 代码示例

function findTwoUniqueNumbers(nums) {
    let xor = 0;
    for (let num of nums) {
        xor ^= num;
    }

    // 找到xor中任意一个为1的位
    let bit = 1;
    while ((bit & xor) === 0) {
        bit <<= 1;
    }

    let a = 0, b = 0;
    for (let num of nums) {
        if (num & bit) {
            a ^= num;
        } else {
            b ^= num;
        }
    }

    return [a, b];
}

// 示例
const nums = [1, 2, 3, 2, 3, 4, 5];
const result = findTwoUniqueNumbers(nums);
console.log(result);

在这些示例中,我们使用了异或运算和位运算来找到只出现一次的两个数字,满足了题目要求的时间复杂度和空间复杂度。

推荐面试题