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

133 阅读3分钟

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

题目描述

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

要求:

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

解题思路

  1. 理解问题

    • 题目要求我们找到数组中唯一一个出现一次的数字。
    • 数组中的其他数字都出现了两次。
  2. 数据结构选择

    • 由于我们需要在 O(n) 时间内完成,并且尽量减少额外空间的使用,可以考虑使用位运算。
  3. 算法步骤

    • 使用异或运算(XOR)来解决这个问题。异或运算有一个特性:a ^ a = 0 和 a ^ 0 = a。因此,如果我们将数组中所有数字进行异或运算,最终结果就是那个唯一的数字。

图解

假设我们有以下数组:cards = [1, 1, 2, 2, 3, 3, 4, 5, 5]

  1. 初始化 result = 0

  2. 遍历数组中的每一个元素,并对 result 进行异或运算:

    • result = 0 ^ 1 = 1
    • result = 1 ^ 1 = 0
    • result = 0 ^ 2 = 2
    • result = 2 ^ 2 = 0
    • result = 0 ^ 3 = 3
    • result = 3 ^ 3 = 0
    • result = 0 ^ 4 = 4
    • result = 4 ^ 5 = 1
    • result = 1 ^ 5 = 4

最终 result 的值为 4,即唯一的数字。

代码详解

public class Main { public static int solution(int[] inp) { if (inp == null || inp.length == 0) { throw new IllegalArgumentException("输入数组不能为空"); }

    int result = 0;
    for (int num : inp) {
        result ^= num;
    }
    return result;
}

public static void main(String[] args) {
    System.out.println("Test case 1: " + (solution(new int[]{1, 1, 2, 2, 3, 3, 4, 5, 5}) == 4));
    System.out.println("Test case 2: " + (solution(new int[]{0, 1, 0, 1, 2}) == 2));
    System.out.println("Test case 3: " + (solution(new int[]{7, 3, 3, 7, 10}) == 10));
    System.out.println("Test case 4: " + (solution(new int[]{1}) == 1));
 }
}
  1. 输入检查

    • 在 solution 方法中,首先检查输入数组是否为空或长度为0,如果是,则抛出异常。
  2. 异或运算

    • 初始化 result 为 0。
    • 遍历数组中的每一个元素,并对 result 进行异或运算。
  3. 返回结果

    • 最终 result 就是那个唯一的数字。
  4. 测试用例

    • 在 main 方法中,添加了多个测试用例,包括边界情况(只有一个元素的数组),以确保代码的正确性。

知识点总结

  1. 异或运算(XOR)

    • 异或运算的特性:a ^ a = 0 和 a ^ 0 = a
    • 通过异或运算,可以将数组中出现两次的数字相互抵消,最终剩下的就是唯一的数字。
  2. 时间复杂度

    • 该算法的时间复杂度为 O(n),其中 n 是数组的长度。
  3. 空间复杂度

    • 该算法的空间复杂度为 O(1),因为我们只使用了一个额外的变量 result

学习建议

  1. 理解异或运算

    • 异或运算在解决一些特定问题时非常高效,尤其是在处理重复元素的问题时。建议深入理解异或运算的特性,并尝试在其他问题中应用。
  2. 练习边界情况

    • 在编写代码时,务必考虑边界情况,如空数组、只有一个元素的数组等。这有助于提高代码的健壮性。
  3. 多做练习

    • 通过多做类似的题目,可以更好地掌握位运算和其他优化技巧。建议在 LeetCode、Codeforces 等平台上寻找类似的题目进行练习。
  4. 代码风格

    • 保持良好的代码风格,如适当的注释、清晰的变量命名等,有助于提高代码的可读性和可维护性。