找出独特的数字 | 豆包MarsCode AI刷题
给定一个班级,每个同学手上有一张卡片,上面有一个整数。除了一个数字以外,所有数字都恰好出现两次。我们需要找到那个数字,它在数组中只出现了一次。
要求我们设计一个算法,使得时间复杂度为 O(n),其中 n 是卡片的数量。同时,要求尽量减少额外空间的使用,以提高算法的空间效率。
思路
-
暴力解法 最简单的解决办法是使用哈希表(或字典)来记录每个数字出现的次数。然后遍历哈希表,找到只出现一次的数字。这种方法的时间复杂度为 O(n),空间复杂度也为 O(n),因为需要存储哈希表的数据。
-
优化方法:使用异或运算 由于题目中要求我们尽量减少额外空间的使用,我们可以考虑不使用额外的存储空间,利用数字的特性来优化解决方案。异或(XOR)运算是一个非常适合这个问题的技巧。下面是具体的思路:
- 异或运算的性质:
a ^ a = 0:任何数与自己异或的结果为 0。a ^ 0 = a:任何数与 0 异或的结果是它本身。- 异或运算满足交换律和结合律,这意味着我们可以任意顺序地进行异或操作。
- 解题思路:
- 如果数组中的数字都成对出现,那么对于成对的数字,异或的结果必然是 0。因为
a ^ a = 0,所以所有成对的数字会“相互抵消”。 - 剩下的唯一没有配对的数字,它的异或结果将是该数字本身。
- 因此,遍历数组对每个数字进行异或操作,最终的结果就是那个只出现一次的数字。
- 如果数组中的数字都成对出现,那么对于成对的数字,异或的结果必然是 0。因为
这种方法不仅时间复杂度为 O(n),而且空间复杂度为 O(1),因为我们只用了一个额外的变量来保存异或结果。
- 异或运算的性质:
步骤
- 初始化一个变量
result为 0。 - 遍历数组中的每个数字,对于每个数字,更新
result = result ^ num。 - 遍历结束后,
result中保存的就是那个唯一出现一次的数字。
算法复杂度分析
- 时间复杂度:O(n),因为我们只遍历了一遍数组。
- 空间复杂度:O(1),因为我们只用了一个额外的变量来存储异或结果。