第一天刷题:找到唯一的卡片数字 | 豆包MarsCode AI刷题

63 阅读2分钟

问题描述

在一个班级中,每位同学都有一张卡片,上面写有一个整数。除了一个数字之外,所有的数字都恰好出现了两次。我们的任务是找到这个“独特的数字”,即唯一出现一次的数字。

要求

  1. 设计一个算法,时间复杂度为 O(n)O(n)O(n),其中 nnn 是班级人数。
  2. 尽量减少额外空间使用。

思路解析

这个问题的关键在于如何高效找到唯一出现的数字。传统方法可能会想到排序或用哈希表统计频率,但这些方法都可能不满足空间优化或时间要求。

异或运算(XOR) 是解决此类问题的最佳工具。异或运算具有以下特性:

  • 一个数与自身异或结果为 0(a ^ a = 0)。
  • 任何数与 0 异或结果为它本身(a ^ 0 = a)。
  • 异或运算满足交换律和结合律,即 (a ^ b) ^ c = a ^ (b ^ c)

通过利用这些特性,可以得出以下结论:

  • 将所有卡片数字进行异或操作,成对的数字会全部抵消为 0,唯一不重复的数字则会保留在结果中。

  • 以下是实现此算法的代码: public class Main { public static int solution(int[] cards) { int result = 0; // 初始化结果为0 for (int card : cards) { result ^= card; // 每个数字与result异或 } return result; // 返回最终结果 }

    public static void main(String[] args) { 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); // 测试 } } 代码解释

  1. solution 方法初始化 result 为 0。
  2. 通过 for 循环遍历数组中的每个 card,并用 result ^= card 将每个数字依次与 result 异或。
  3. 成对出现的数字会在异或过程中相互抵消(结果为 0),最终留下的 result 就是唯一不重复的数字。
  4. main 方法中加入了测试用例,可以用来验证代码的正确性。

心得总结

  • 异或的高效性:利用异或特性解决这类问题,不仅能将算法时间复杂度优化为 O(n)O(n)O(n),还能避免额外空间开销。
  • 边界情况的考虑:算法简洁,适用于任何数组中有且仅有一个数字不重复的情况。
  • 代码简洁:仅用几个行的代码实现目标,是算法设计中的一个经典技巧。