做题笔记:找单独的数 | 豆包MarsCode AI刷题

110 阅读4分钟

做题笔记:找单独的数问题解析

问题描述

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

要求

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

测试样例

  • 样例1:cards = [1, 1, 2, 2, 3, 3, 4, 5, 5],输出:4
  • 样例2:cards = [0, 1, 0, 1, 2],输出:2
  • 样例3:cards = [7, 3, 3, 7, 10],输出:10

约束条件

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

思路

数据结构选择

由于题目要求时间复杂度为 O(n),并且尽量减少额外空间的使用,我们可以考虑使用位运算来解决这个问题。

算法步骤

  1. 异或运算:异或运算有一个非常有用的性质:

    • 任何数和 0 做异或运算,结果仍然是原来的数,即 a ^ 0 = a
    • 任何数和其自身做异或运算,结果是 0,即 a ^ a = 0
    • 异或运算满足交换律和结合律,即 a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b
  2. 利用异或运算:我们可以遍历整个列表,将所有数字进行异或运算。由于其他数字都出现两次,它们会相互抵消,最终剩下的就是唯一出现一次的数字。

图解

假设输入 cards = [1, 1, 2, 2, 3, 3, 4, 5, 5]

  1. 初始 result = 0
  2. 第一次循环:result = 0 ^ 1 = 1
  3. 第二次循环:result = 1 ^ 1 = 0
  4. 第三次循环:result = 0 ^ 2 = 2
  5. 第四次循环:result = 2 ^ 2 = 0
  6. 第五次循环:result = 0 ^ 3 = 3
  7. 第六次循环:result = 3 ^ 3 = 0
  8. 第七次循环:result = 0 ^ 4 = 4
  9. 第八次循环:result = 4 ^ 5 = 1
  10. 第九次循环:result = 1 ^ 5 = 4

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

代码详解

   public class Main {
   public static int solution(int[] cards) {
    // 初始化结果为0
    int result = 0;
  
    // 遍历列表中的每个数字
    for (int card : cards) {
        // 对每个数字进行异或运算
        result ^= card;
    }
    
    // 返回最终结果
    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. 初始化结果int result = 0;

    • 初始化 result 为 0
  2. 遍历列表for (int card : cards)

    • 使用增强型 for 循环遍历 cards 数组中的每个元素,将其赋值给变量 card
  3. 异或运算result ^= card;

    • 对 result 和当前的 card 进行异或运算,并将结果赋值回 result
  4. 返回结果return result;

    • 返回 result,即唯一出现一次的数字。

总结知识点

  1. 异或运算

    • a ^ 0 = a
    • a ^ a = 0
    • 异或运算满足交换律和结合律
  2. 时间复杂度:O(n)

    • 遍历一次数组,时间复杂度为 O(n)。
  3. 空间复杂度:O(1)

    • 只使用了常数级别的额外空间。

梳理分析

  1. 问题理解:找到唯一出现一次的数字。
  2. 数据结构选择:使用位运算。
  3. 算法步骤:遍历数组,对每个元素进行异或运算。
  4. 优化:通过异或运算,避免了使用额外的空间。

学习建议

  1. 理解异或运算

    • 异或运算在处理重复元素时非常有用,建议多练习相关的题目。
  2. 时间复杂度分析

    • 理解并分析算法的时间复杂度,确保算法在给定约束条件下能够高效运行。
  3. 空间复杂度优化

    • 尽量减少额外空间的使用,提升算法的效率。
  4. 多练习

    • 通过多做类似的题目,加深对异或运算和位运算的理解。