“找单独的数”题目解析 | 豆包MarsCode AI刷题

63 阅读2分钟

问题描述

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

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

以下是题目给出的代码部分

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);
    }
}

本题通过分析,代码时间复杂度为 O(n),如果还要尽量减少额外空间的使用,可以考虑使用位运算来解决。具体为如果一个数字只出现一次,那么它与 0 进行异或运算后,结果仍然是这个数字本身。首先遍历整个数组,对每个元素进行异或运算。出现两次的数字在异或运算后会相互抵消,那么最终剩下的就是唯一不重复的数字。 思路大概了解后,我们可以先得出伪代码如下:

result = 0
for each card in cards:
    result = result XOR card
return result

之后可以编写正确的java代码

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
        int[] test1 = {1, 1, 2, 2, 3, 3, 4, 5, 5};
        int[] test2 = {0, 1, 0, 1, 2};
        int[] test3 = {7, 3, 3, 7, 10};

        System.out.println("Test 1: " + (solution(test1) == 4));
        System.out.println("Test 2: " + (solution(test2) == 2));
        System.out.println("Test 3: " + (solution(test3) == 10));
    }
}

进行测试,结果满足题目要求

Test 2: true
Test 3: true
Test 1: true

题目解答完成 除了使用异或运算,本题还可以使用哈希表(HashMap)来解决这个问题,具体步骤为先遍历数组,将每个数字作为键存储在哈希表中,并记录每个数字出现的次数。之后再次遍历哈希表,找到出现次数为1的数字。哈希表解法的美中不足之处在于,相比文中的解法,它虽然有效,但是这种方法会使用额外的空间,不满足题目中“尽量减少额外空间的使用”的要求。