问题描述
给定一个整数数组,数组中的数字有两个只出现一次,其他数字出现两次。要求在时间复杂度 O(n)
、空间复杂度 O(1)
的情况下将这两个数字找出来。题目链接:**点我**
样例输入输出
输入:[1, 2, 1, 3, 2, 5]
输出:[3, 5]
输入:[1, 3]
输出:[1, 3]
问题解法
此题最简单的做法是用 map 来存储数字出现的次数,但是这需要耗费 O(n)
的空间,不满足题目要求。因此需要考虑位运算的解法,此解法参考:https://leetcode-cn.com/problems/single-number-iii/solution/cai-yong-fen-zhi-de-si-xiang-jiang-wen-ti-jiang-we/。具体做法是:先将数组中数字进行异或运算,得到两个出现一次的数字 A、B 的异或值 X,因为 A、B 不相等,所以 X 不等于 0,那 X 必然存在至少一个位数为 1,根据 x & (-x)
可以获得 X 的最低位为 1 的数,记为 mask,此时对数组中的每个数分别与 mask 进行与运算,可以将原数组分成两个部分:一个是结果为 0 的子数组,一个是结果为 1 的子数组。此时,数字相同(出现两次)的会被分配到同一个子数组中,而 A 和 B(只出现一次的数字)必然分配到不同的子数组中(因为是按照 A 和 B 的异或值的某一位为 1 来区分的)。可以看出,此时两个子数组的特点:只有一个数字出现一次,其他数字出现两次。那么此时求解就可以简化成:在两个子数组中,分别找出只出现一次的数字。
代码如下
1 | class Solution { |