找单独的数 | 豆包MarsCode AI 刷题

115 阅读3分钟

找单独的数 | 豆包MarsCode AI 刷题

在编程的世界里,解决问题的技巧和效率往往决定了代码的质量。今天,我们来探讨一个有趣的问题:在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。除了一个数字之外,所有的数字都恰好出现了两次。我们的任务是帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。这个问题不仅考验了我们对算法的理解,还要求我们在时间和空间复杂度上做出优化。

问题描述

在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。

要求

  • 设计算法,使其时间复杂度为 O(n),其中 n 是班级的人数。
  • 尽量减少额外空间的使用,以体现你的算法优化能力。

测试样例

  • 样例1

    • 输入:cards = [1, 1, 2, 2, 3, 3, 4, 5, 5]
    • 输出:4
    • 解释:拿到数字 4 的同学是唯一一个没有配对的。
  • 样例2

    • 输入:cards = [0, 1, 0, 1, 2]
    • 输出:2
    • 解释:数字 2 只出现一次,是独特的卡片。
  • 样例3

    • 输入:cards = [7, 3, 3, 7, 10]
    • 输出:10
    • 解释:10 是班级中唯一一个不重复的数字卡片。

约束条件

  • 1 ≤ cards.length ≤ 1001
  • 0 ≤ cards[i] ≤ 1000
  • 班级人数为奇数
  • 除了一个数字卡片只出现一次外,其余每个数字卡片都恰好出现两次

解题思路

位运算的巧妙应用

在这个问题中,我们可以利用位运算中的异或(XOR)操作来找到那个唯一的数字。异或操作有一个非常有用的性质:对于任何整数 aa ^ a = 0,并且 a ^ 0 = a。这意味着,如果我们对数组中的所有数字进行异或操作,成对出现的数字会被抵消掉,最终剩下的就是那个唯一的数字。

代码实现

java

复制代码

public class Main {
    public static int solution(int[] cards) {
        int res = 0;
        for (int i = 0; i < cards.length; i++) {
            res ^= cards[i];
        }
        return res;
    }

    public static void main(String[] args) {
        // 测试样例
        System.out.println(solution(new int[]{1, 1, 2, 2, 3, 3, 4, 5, 5}) == 4); // 输出: true
        System.out.println(solution(new int[]{0, 1, 0, 1, 2}) == 2); // 输出: true
        System.out.println(solution(new int[]{7, 3, 3, 7, 10}) == 10); // 输出: true
    }
}

代码解析

  • solution 方法

    • 初始化一个变量 res 为 0。
    • 遍历数组 cards,对每个元素进行异或操作,结果存储在 res 中。
    • 最终返回 res,即为那个唯一的数字。
  • main 方法

    • 测试了三个样例,验证了 solution 方法的正确性。

时间和空间复杂度分析

  • 时间复杂度:O(n),其中 n 是数组的长度。我们只需要遍历数组一次。
  • 空间复杂度:O(1),我们只使用了常数级的额外空间。

总结

通过利用位运算的特性,我们能够高效地解决这个问题,不仅满足了时间复杂度的要求,还最大限度地减少了额外空间的使用。这种方法不仅简洁,而且在实际应用中也非常实用。希望这篇文章能帮助你更好地理解和掌握这一技巧。如果你有任何问题或建议,欢迎在评论区留言讨论!