【剑指Offer-56-I】数组中数字出现的次数
问题
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例
输入: nums = [1,2,10,4,1,4,3,3]
输出: [2,10] 或 [10,2]
解答
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int x = 0, y = 0, m = 1, n = 0; // x与y为只出现一次的数字
for (int i : nums) n ^= i; // n为x与y异或的值
while ((n & m) == 0) m <<= 1; // 求出x和y不同的1位二进制位
for (int i : nums) { // 分别求解x和y
if ((i & m) == 0) x ^= i;
else y ^= i;
}
return vector<int> {x, y};
}
};
重点思路
异或运算有个重要的性质,两个相同数字异或为0,即对于任意整数a
有a⊕a=0
。因此,若将nums
中所有数字执行异或运算,留下的结果则为出现一次的数字x
。
当要求解两个只出现一次的数字该怎么办呢?首先这两个数字肯定不同,其二进制位至少有一位不同,我们可以通过不同的这一位将原数组分为含x
和含y
的两个数组,此时这两个数组只包含1个不同数字,分别求解即可。