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

39 阅读3分钟

问题描述

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

要求:

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

测试样例

样例1:

输入:cards = [1, 1, 2, 2, 3, 3, 4, 5, 5]
输出:4
解释:拿到数字 4 的同学是唯一一个没有配对的。

样例2:

输入:cards = [0, 1, 0, 1, 2]
输出:2
解释:数字 2 只出现一次,是独特的卡片。

样例3:

输入:cards = [7, 3, 3, 7, 10]
输出:10
解释:10 是班级中唯一一个不重复的数字卡片。

约束条件

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

解法

第一种常见的解决方案是先对数组进行排序,然后遍历数组以寻找那个只出现一次的数字。这个方法的基本思路是,通过对数组进行排序,我们可以将相同的数字放置在相邻的位置。然后,遍历排序后的数组,逐一检查当前项与其后续项是否相同。如果某个数字与后一项不相等,或者后一项不存在(即当前项为数组的最后一项),那么当前项即为唯一出现的那个数字。因为我们可以通过比较相邻的元素来找出不同的那一个。 然而,这种方法的时间复杂度是由排序过程决定的。在最坏情况下,排序算法的时间复杂度是 O(n log n),无论采用快速排序、归并排序还是堆排序等常见的排序算法,都无法做到 O(n) 的时间复杂度。因此,这种方法在时间效率上并不符合题目的要求,特别是当数组的大小非常大时,排序所带来的额外开销会显得不合适。因此,我们需要考虑其他更加高效的算法。 第二种方法。由于题目要求时间复杂度为O(n),也就是说只能遍历一遍数组。异或运算有一种特性,a^0=a,a^a=0,0^0=0,而题目中说明每种数字最多出现两次,也就是将这些出现了两次的数两两异或的结果是0,将他们异或的结果继续进行异或结果为1,设剩下的数为b,那么整个数组异或的结果将为b^0=b,即可得出唯一出现的那个数。