LeetCode-260只出现一次的数字 III

  • 题目

    给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

  • 思路

    • 哈希表

      统计数组中每个元素出现的次数,再遍历哈希表,输出次数为1的元素

    • 位运算

      通过学习只出现一次的数字我们可以得到:

      \[A\bigoplus A=0 \]

      \[A\bigoplus B=B\bigoplus A \]

      \[A\bigoplus B \bigoplus A=B \]

      因为当数组中只有一个元素出现一次,其他元素出现两次时,将元素中所有元素异或,即可得到该元素

      当数组中有两个元素出现一次(假设为a,b),其他元素为两次,此时将所有元素异或,得到\(a\bigoplus b=sum\),且\(a\bigoplus b \neq 0\),如果为0意味着a,b相等。取sum二进制中的任意一位1,在此位置上,意味着a,b两元素的值不相同,通过\(sum \bigoplus nums[i]==1\)这个条件,就可将数组分为两部分,一部分同在该位置同a相等,一部分同b相等,再将每部分分别求异或和,即可求得这两个元素。

  • Code

    • 哈希表
    class Solution {
    public:
        vector<int> singleNumber(vector<int>& nums) {
            if(nums.size()<=2){
                return nums;
            }
            map<int,int> m;
            for(auto i:nums){
                m[i]+=1;
            }
            vector<int> res;
            for(auto p:m){
                if(p.second==1){
                    res.push_back(p.first);
                }
            }
            return res;
        }
    };
    
    • 位运算
    class Solution {
    public:
        vector<int> singleNumber(vector<int>& nums) {
            int sum=0;
            for(auto i:nums){
                sum^=i;
            }
            int k=-1;
            for (int i = 31; i >= 0 && k == -1; i--) {
                if (((sum >> i) & 1) == 1){
                    k = i;
                }
            }
            int num1=0,num2=0;
            for(auto i:nums){
                if((i>>k)&1){
                    num1^=i;
                }
                else{
                    num2^=i;
                }
            }
            return vector<int>({num1,num2});
        }
    };