掘金Al刷题-找单独的数解析|豆包MarsCode AI刷题

106 阅读2分钟

问题描述

有一堆数字,除了一个数字,其它的数字都是成对出现。班上的每个同学拿一个数字,正好将这些数字全部拿完,问如何快速找到拿了单独数字的同学?

输入格式

  • 空格分隔输入所有的数字

输出格式

  • 单独的那个数字

输入样例

1 1 2 2 3 3 4 5 5

输出样例

4

题目解析

由于题目要求找出单独的数,因此我们可以想到Java中的异或运算操作,即^=

^= 是 Java 中的复合赋值运算符,表示异或赋值运算。它结合了异或运算(^)和赋值运算(=)。具体来说,a ^= b 等价于 a = a ^ b

异或运算(^)的特性

  • 交换律a ^ b = b ^ a
  • 结合律a ^ (b ^ c) = (a ^ b) ^ c
  • 自反性a ^ a = 0
  • 与零的异或a ^ 0 = a

异或运算的应用

在处理成对出现的数字时,异或运算非常有用。因为成对出现的数字在异或运算中会相互抵消,最终剩下的就是单独的那个数字。

算法步骤

  • 初始化一个变量 result 为 0。

  • 遍历数组中的每一个元素,并将它们与 result 进行异或运算。

  • 最终,result 将包含单独的那个数字。

解释

  1. solution(int[] cards)
    这个方法接收一个整数数组 cards,数组中的元素可能成对出现,最终通过异或操作找出那个唯一没有成对的数字。

    • 我们初始化一个变量 result0,然后遍历 cards 数组中的每个数字,进行异或运算 result ^= card。由于异或运算的自反性,相同的数字会被抵消,最终结果 result 就是那个没有成对的数字。
  2. main(String[] args)
    这里我们测试了两个样例,分别是:

    • new int[]{1, 1, 2, 2, 3, 3, 4, 5, 5},这个数组中的唯一单独数字是 4
    • new int[]{0, 1, 0, 1, 2},这个数组中的唯一单独数字是 2

时间复杂度

  • 时间复杂度:O(n),其中 n 是输入数组的长度。我们遍历数组中的每个元素,进行一次异或操作,所以时间复杂度是线性的。
  • 空间复杂度:O(1),我们只使用了常数空间来存储 result 变量。

总结

使用异或运算解决此问题非常高效,因为它能够消除成对出现的数字,最终剩下的就是那个单独的数字。此方法时间复杂度为 O(n),并且只需要常数级别的空间,适合处理较大规模的数据。

代码实现

    public static int solution(int[] cards) {
        // Edit your code here
        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);
    }
}