1. 概述

在本文中,我们将探讨一个经典问题:在一个元素两两成对的数组中,找出唯一一个没有配对的元素。我们将通过示例说明问题,并提供三种不同的解决思路。

文章重点如下:

✅ 问题定义与示例
✅ 暴力解法(O(N²))
✅ 使用 Map(O(N))
✅ 使用位运算 XOR(O(N),最优解)


2. 问题定义

给定一个大小为 N 的整型数组 A,其中 N 为奇数。数组中除了一个元素外,其余每个元素都恰好出现两次。我们的任务是找出那个只出现一次、无法配对的元素

例如,考虑以下数组:

Example

尝试两两配对:

PairedExample

可以看到 4、3、1 都能成对,只有 2 是孤立的。因此,答案是 2。


3. 暴力解法(O(N²))

思路:

对每个元素,遍历整个数组寻找它的配对项。如果找不到,说明就是目标元素。

实现:

algorithm NaiveApproach(A, N):
    for i <- 1 to N:
        isPaired <- false
        for j <- 1 to N:
            if i != j and A[i] == A[j]:
                isPaired <- true
                break
        if not isPaired:
            return A[i]
    return -1

说明:

  • 时间复杂度:**O(N²)**,效率较低
  • 空间复杂度:O(1)

⚠️ 适用于小数据集,不推荐用于大规模数据


4. 使用 Map(O(N))

思路:

使用 Map(或 HashMap)记录每个元素出现的次数,最后遍历 Map 找出出现次数为 1 的元素。

实现:

algorithm MapApproach(A, N):
    map <- create an empty map
    for i <- 1 to N:
        map[A[i]] <- map[A[i]] + 1
    for element in map:
        if element.value == 1:
            return element.key
    return -1

说明:

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)

✅ 适用于大多数场景,但需要额外空间


5. 使用 XOR 位运算(O(N),最优解)

5.1 原理

XOR 位运算具有以下性质:

  • X ^ Y = Y ^ X
  • X ^ X = 0
  • 0 ^ X = X

因此,如果我们将数组中所有元素进行 XOR 操作,成对的元素会被抵消为 0,剩下的就是那个唯一未配对的元素。

举例:

假设数组为 [4, 3, 1, 2, 1, 3, 4],则:

4 ^ 3 ^ 1 ^ 2 ^ 1 ^ 3 ^ 4 
= (4 ^ 4) ^ (3 ^ 3) ^ (1 ^ 1) ^ 2 
= 0 ^ 0 ^ 0 ^ 2 
= 2

5.2 实现:

algorithm XORApproach(A, N):
    answer <- 0
    for i <- 1 to N:
        answer <- answer XOR A[i]
    return answer

说明:

  • 时间复杂度:O(N)
  • 空间复杂度:O(1)

✅ 最优解法,推荐使用


6. 总结

方法 时间复杂度 空间复杂度 是否推荐
暴力解法 O(N²) O(1)
使用 Map O(N) O(N)
使用 XOR O(N) O(1) ✅✅✅

XOR 解法是本问题的最佳解法,兼具时间和空间优势
✅ 掌握 XOR 的性质在面试中非常实用,建议熟练掌握
⚠️ 注意:该问题前提是只有一个元素未配对,如果有多个则 XOR 方法不再适用



原始标题:Finding the Only Unpaired Element in the Array