青训营X豆包MarsCode 技术训练营第一课 | 豆包MarsCode AI 刷题

51 阅读3分钟

题目解析:寻找数组中唯一出现一次的数字

题目背景

在计算机科学中,数组是一种常见的数据结构,用于存储一系列相同类型的元素。在某些情况下,我们需要从数组中找出唯一出现一次的元素。这个问题在算法和数据结构中非常常见,尤其是在处理去重、查找唯一元素等场景中。

题目描述

给定一个整数数组 cards,其中除了一个数字只出现一次外,其他所有数字都出现了两次。我们需要编写一个函数 solution,返回这个唯一出现一次的数字。

解题思路

解决这个问题的关键在于利用异或运算的特性。异或运算(XOR)是一种二进制运算,具有以下特性:

  1. 交换律a ^ b = b ^ a
  2. 结合律a ^ (b ^ c) = (a ^ b) ^ c
  3. 自反性a ^ a = 0
  4. 零元素a ^ 0 = a

基于这些特性,我们可以通过遍历数组,将所有元素进行异或运算,最终得到的结果就是那个唯一出现一次的数字。因为所有出现两次的数字在异或运算中会相互抵消,最终剩下的就是唯一出现一次的数字。

代码实现

public class Main {
    public static int solution(int[] cards) {
        int uniqueCard = 0;
        for (int card : cards) {
            uniqueCard ^= card;
        }
        return uniqueCard;
    }

    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);
        System.out.println(solution(new int[]{7, 3, 3, 7, 10}) == 10);
    }
}

image.png image.png

代码分析

  1. 初始化:我们初始化一个变量 uniqueCard 为 0。
  2. 遍历数组:使用增强型 for 循环遍历数组中的每个元素。
  3. 异或运算:将当前元素与 uniqueCard 进行异或运算,并将结果赋值给 uniqueCard
  4. 返回结果:遍历结束后,uniqueCard 中存储的就是唯一出现一次的数字。

时间复杂度分析

该算法的时间复杂度为 O(n),其中 n 是数组的长度。因为我们只需要遍历一次数组,所以时间复杂度是线性的。

空间复杂度分析

该算法的空间复杂度为 O(1),因为我们只使用了一个额外的变量 uniqueCard,没有使用额外的数组或数据结构。

个人思考与分析

在解决这个问题时,我们利用了异或运算的特性,这是一种非常巧妙的方法。异或运算不仅在解决这个问题时非常高效,而且在其他一些算法问题中也有广泛的应用,比如在加密算法中。

此外,这个问题还可以通过其他方法来解决,比如使用哈希表来记录每个数字出现的次数,或者使用排序算法对数组进行排序,然后遍历数组找到唯一出现一次的数字。然而,这些方法的时间复杂度和空间复杂度通常不如异或运算高效。

总结

通过异或运算来解决这个问题,不仅代码简洁,而且时间复杂度和空间复杂度都非常优秀。这种方法充分利用了异或运算的特性,是一种非常高效的解决方案。在实际编程中,我们应该灵活运用各种算法和数据结构,选择最优的解决方案来解决问题。

扩展思考

如果数组中存在多个唯一出现一次的数字,该如何解决?这个问题可以通过将数组分成两部分,分别应用异或运算来解决。具体方法可以参考其他相关算法问题。

结论

通过本文的分析,我不仅掌握了如何使用异或运算来解决数组中唯一出现一次的数字问题,还深入理解了异或运算的特性和应用。希望这篇文章能够帮助你在算法学习和编程实践中获得更多的启发和思考。