剑指 Offer 56 - I. 数组中数字出现的次数 - 力扣(LeetCode)

剑指 Offer 56 - I. 数组中数字出现的次数 - 力扣(LeetCode)

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

思路:分组异或

看到数出现偶数次和奇数次,应该想到用异或做。因为对一个数异或偶数次,等于异或0。

考虑只有一个数出现奇数次的情况:这种情况下,只需将所有数进行异或,得到的就是出现奇数次的数。

现在考虑两个数出现奇数次的情况,设这两个数分别为a和b

  1. 对所有数进行异或得到的结果时a^b ,设x= a^b
  2. 考察x中为1的某一位,该位为1,说明a和b的这一位不相同,而两个相同的数每一位都相同。因此我们可以以这一位是否为1,将所有数分为两组,分别进行异或,得到的答案就是a和b
class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        int x=nums[0];
        for (int i=1;i<nums.size();i++)
        {
            x^=nums[i];
        }
        int x1=0;
        int x2=0;
        int k=0;
        while (!(x&1))
        {
            k++;
            x>>=1;
        }
        for (int i=0;i<nums.size();i++)
        {
            if (1&(nums[i]>>k))
                x1^=nums[i];
            else
                x2^=nums[i];
        }
        vector<int> v={x1,x2};
        return v;
    }
};
posted @ 2022-10-24 01:39  sjwsjwsjwsjw1234  阅读(45)  评论(0)    收藏  举报