问题描述

在这里插入图片描述

思路分析

这道题的目标是找到数组中只出现了一次的数字,其余的数字均出现了两次。由于题目要求时间复杂度为O(n),并且要求尽量减少额外空间的使用,因此我们可以考虑使用位运算来解决这个问题。

  1. 异或运算的特性:异或(XOR)运算具有以下几个重要特性:

    • 对于任意整数 a,有 a ⊕ a = 0(相同的数字异或会抵消)。
    • 对于任意整数 a,有 a ⊕ 0 = a 。
    • 异或运算满足交换律和结合律,即顺序无关,a ⊕ b ⊕ c = a ⊕ c ⊕ b 。
  2. 利用异或找到唯一数字

    • 如果我们将所有的数字依次进行异或运算,那么那些成对出现的数字会互相抵消(异或为 0),最终剩下的就是那个只出现一次的数字。
    • 这样我们可以在一次遍历中完成计算,并且不需要额外的存储空间,达到 O(n) 的时间复杂度和 O(1) 的空间复杂度。

算法步骤

  1. 初始化一个变量 unique_number 为 0。
  2. 遍历数组中的每个元素,并将 unique_number 与该元素进行异或运算。
  3. 遍历结束后,unique_number 中存储的就是只出现一次的数字。

复杂度分析

  • 时间复杂度:O(n),因为我们只需要遍历一次数组。
  • 空间复杂度:O(1),因为只用了一个额外变量 unique_number

参考代码(Python)

def solution(inp):
    unique_number = 0
    for number in inp:
        unique_number ^= number  # 使用异或操作
    return unique_number

if __name__ == "__main__":

    print(solution([1, 1, 2, 2, 3, 3, 4, 5, 5]) == 4)
    print(solution([0, 1, 0, 1, 2]) == 2)
    print(solution([7, 3, 3, 7, 10]) == 10)

代码分析

  1. 初始化 unique_number 为 0

    • unique_number 变量用于存储最终结果。初始化为 0 是因为异或的中立元素是 0(也就是 a ⊕ 0 = a )。
  2. 遍历输入数组 inp

    • 代码通过 for number in inp: 遍历输入数组 inp 中的每一个数字 number
  3. 异或操作 unique_number ^= number

    • 对每个数字 number,都与当前的 unique_number 进行异或运算。
    • 由于数组中除了一个数字其他都成对出现,所以这些成对的数字将互相抵消(每一对会变成 0),最终剩下的 unique_number 就是唯一没有成对的数字。
  4. 返回结果

    • 最终 unique_number 存储的就是那个唯一出现一次的数字。

流程示例

假设输入是 [1, 1, 2, 2, 3, 3, 4, 5, 5]

  • 初始化 unique_number = 0
  • 遍历数组并执行异或操作:
    • 0 ^ 1 = 1
    • 1 ^ 1 = 0 (1 和 1 抵消,结果回到 0)
    • 0 ^ 2 = 2
    • 2 ^ 2 = 0 (2 和 2 抵消,结果回到 0)
    • 0 ^ 3 = 3
    • 3 ^ 3 = 0 (3 和 3 抵消,结果回到 0)
    • 0 ^ 4 = 4 (4 没有对手,结果是 4)
    • 4 ^ 5 = 1
    • 1 ^ 5 = 4 (5 和 5 抵消,最终结果是 4)

最终输出 4,即唯一的数字。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐