【剑指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,即对于任意整数aa⊕a=0。因此,若将nums中所有数字执行异或运算,留下的结果则为出现一次的数字x

当要求解两个只出现一次的数字该怎么办呢?首先这两个数字肯定不同,其二进制位至少有一位不同,我们可以通过不同的这一位将原数组分为含x和含y的两个数组,此时这两个数组只包含1个不同数字,分别求解即可。

posted @ 2021-03-06 15:12  tmpUser  阅读(38)  评论(0编辑  收藏  举报