《剑指offer》面试题56 - I. 数组中数字出现的次数

问题描述

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

输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
示例 2:

输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
 

限制:

2 <= nums <= 10000

代码

首先给一个时间复杂度\(O(N)\)空间复杂度\(O(N)\)的算法:

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        map<int,int> table;
        vector<int> ans;
        for(int& num:nums)
        {
            ++table[num];
        }
        for(auto &num:table)
        {
            if(num.second == 1)ans.push_back(num.first);
        }
        return ans;
    }
};

结果

执行用时 :164 ms, 在所有 C++ 提交中击败了5.22%的用户
内存消耗 :20.4 MB, 在所有 C++ 提交中击败了100.00%的用户

代码

再给一个时间复杂度\(O(N\log(N))\)空间复杂度\(O(1)\)的算法:

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        int i,n  =nums.size();
        if(n == 2)return nums;
         vector<int> ans;
        sort(nums.begin(),nums.end());
        if(nums[0]!=nums[1])ans.push_back(nums[0]);
        if(nums[n-1]!=nums[n-2])ans.push_back(nums[n-1]);
        for(i = 1; i < n-1; ++i)
        {
            if(nums[i] != nums[i-1] && nums[i]!= nums[i+1])
                ans.push_back(nums[i]);
        }
        return ans;
    }
};

结果

执行用时 :76 ms, 在所有 C++ 提交中击败了14.53%的用户
内存消耗 :16.5 MB, 在所有 C++ 提交中击败了100.00%的用户

代码

最后给一个时间复杂度\(O(N)\)空间复杂度\(O(1)\)的算法:

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        int i,n  =nums.size(),x = 0;
        if(n == 2)return nums;
        vector<int> ans(2,0);
        //将其全部 '异或' 起来,我们知道相同的两个数 '异或' 的话为0,那么两个1都抵消了,就剩1和6 '异或' 起来
        for(int &num:nums)
            x ^= num;
        //我们用 x &= -x 来取出最右端为 ‘1’ 的位,
        x &= -x;
        //目标数必然分散在两个数组中,而且相同的数必然落在同一个数组中,相当于求解两个从只有一个元素只出现一次,其余元素都出现两次的数组中找出这一个元素的问题
        for(int &num:nums)
        {
            if(x & num)ans[0] ^= num;
            else ans[1] ^= num; 
        }
        return ans;
    }
};

结果

执行用时 :36 ms, 在所有 C++ 提交中击败了64.01%的用户
内存消耗 :16.2 MB, 在所有 C++ 提交中击败了100.00%的用户
posted @ 2020-05-01 08:38  曲径通霄  阅读(86)  评论(0编辑  收藏  举报