📌  相关文章
📜  从它们的总和与XOR中找出两个数字(1)

📅  最后修改于: 2023-12-03 14:49:24.043000             🧑  作者: Mango

从它们的总和与XOR中找出两个数字

有一个数组,里面有两个数字只出现了一次,剩下的数字都出现了两次。在这个数组中找出这两个只出现了一次的数字。

思路

因为只有两个数字出现了一次,其他数字都出现了两次,因此可以将所有数字异或起来,得到的结果就是这两个只出现了一次数字的异或和。我们可以将所有数字按照二进制位分为两组:第一组是数字二进制某位为1的数字,第二组是数字二进制某位为0的数字。那么我们来考虑,为什么可以这样分组?

我们将两个不同的数字进行异或操作,得到的结果中,至少有一位是1,因为他们是不同的数字,这一位要么是其中一个数字的该位为1,要么是另一个数字的该位为1,因此,我们以这一位是否为1,就可以将它们分为两个组,而这个1位上如果是相同数字,它们会被分在相同组中,因为它们异或后,这个1位还是1。这样,这两个只出现了一次的数字就被分到了两个不同的组中。

我们可以分别对这两个组中的数字进行异或操作,得到的结果就是这两个只出现了一次数字。

代码实现
def find_two_numbers(nums: List[int]) -> Tuple[int, int]:
    # 把所有数字异或起来
    xor_result = 0
    for num in nums:
        xor_result ^= num
    # 找到异或结果中第一位为1的位置
    bit = 1
    while (xor_result & bit) == 0:
        bit <<= 1
    # 按照这一位分成两个组
    num1, num2 = 0, 0
    for num in nums:
        if num & bit:
            num1 ^= num
        else:
            num2 ^= num
    return num1, num2

这个函数接受一个整数数组 nums 作为参数,返回一个元组 (num1, num2),表示在 nums 中只出现了一次的两个数字。