#青训营笔记创作活动

52 阅读3分钟

在这个问题中,我们需要在一个整数数组中找到唯一一个出现一次的数字。数组中的其他数字都恰好出现两次。这个问题的一个关键点是,我们需要在时间复杂度为 O(n) 的情况下解决,并且尽量减少额外空间的使用。

数据结构的选择

由于题目要求时间复杂度为 O(n),并且尽量减少额外空间的使用,我们可以考虑使用位操作来解决这个问题。具体来说,异或(XOR)操作是一个非常合适的选择,因为它具有以下特性:

  1. x ^ x = 0:任何数与自身异或的结果为 0。
  2. x ^ 0 = x:任何数与 0 异或的结果为该数本身。
  3. 异或操作满足交换律和结合律:这意味着我们可以任意顺序对数组中的元素进行异或操作,结果不会受到影响。

算法步骤

  1. 初始化一个变量 result 为 0:这个变量将用于存储最终的结果。
  2. 遍历数组中的每一个元素:对每个元素进行异或操作,并将结果存储在 result 中。
  3. 返回 result:遍历结束后,result 中存储的就是唯一一个出现一次的数字。

详细解释

  1. 初始化 result 为 0:因为任何数与 0 异或的结果还是该数本身,所以初始化为 0 不会影响最终结果。

  2. 遍历数组中的每个元素

    • 对于数组中的每个元素 card,我们执行 result ^= card
    • 由于异或操作的特性,成对出现的数字会相互抵消,最终剩下的就是单独的那个数字。
  3. 返回 result:遍历结束后,result 中存储的就是唯一一个出现一次的数字。

为什么选择异或操作

异或操作在这里非常合适,因为它不仅满足题目要求的时间复杂度 O(n),而且不需要额外的空间。异或操作的特性使得我们可以在一次遍历中完成所有计算,并且不需要额外的数据结构来存储中间结果。

进一步思考

虽然异或操作已经很好地解决了这个问题,但我们还可以进一步思考是否有其他方法可以解决这个问题。例如,我们可以考虑使用哈希表来记录每个数字的出现次数,但这会增加额外的空间复杂度。因此,异或操作仍然是最佳选择。

总结

通过使用异或操作,我们可以在 O(n) 的时间复杂度内找到数组中唯一一个出现一次的数字,并且不需要额外的空间。这种方法不仅高效,而且简洁,完美地满足了题目的要求。public class Main { public static int solution(int[] cards) { int result = 0; for (int card : cards) { result ^= card; // 对所有元素进行异或操作 } return result; }

public static void main(String[] args) {
    // Add your test cases here
    
    System.out.println(solution(new int[]{1, 1, 2, 2, 3, 3, 4, 5, 5}) == 4);
    System.out.println(solution(new int[]{0, 1, 0, 1, 2}) == 2);
}

}