面試題56-I:數組中數字出現的次數(C++)


題目地址:https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/

題目描述

一個整型數組 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]

解題思路

哈希表:初看這道題目,發現又是計數問題,對於計數問題,哈希表是一種很方便的方法,在這里我們使用哈希表arr計數nums數組中的每個元素出現的次數,對出現一次的元素,我們將它存入到數組res中,最后返回res即可,不過空間復雜度不滿足O(1)要求。

位運算(異或):首先要明確異或的含義,異或顧名思義就是兩者相同,則異或結果為0,否則結果為1,簡言之,n^n=0,n^m=1,需要注意的是任何數與0異或結果為它本身,即n^0=n。回歸到本題,出來2個數出現了一次之外,其余數均出現了兩次。分析題目,如果除了一個數出現一次外,其余數字出現的次數均出現的次數為2次,那么這個元素如何求呢?不難發現,只要我們遍歷數組全員異或一下即可得到,這是因為異或運算具有交換率,兩兩相同的元素異或結果必然為0,這樣最后就只剩下出現一次的那個元素了。對於兩個出現一次的元素求解,我們可以采用二進制的方法將所有元素分成兩組,使得兩個只出現一次的元素在不同的組中,以及相同的元素被分配到相同的組中,然后對兩個組分別進行異或運算,即可得到兩個只出現一次的元素。其中,我們假設兩個只出現一次的元素分別為a和b,那么所有元素異或的結果就是a和b的異或結果。

程序源碼

哈希表

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        if(nums.size() == 0) return {};
        unordered_map<int, int> arr;
        vector<int> res;
        for(int i = 0; i < nums.size(); i++)
        {
            arr[nums[i]] += 1;
        }
        for(int i = 0; i < nums.size(); i++)
        {
            if(arr[nums[i]] == 1)
            res.push_back(nums[i]);
        }
        return res;
    }
};

異或運算

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        if(nums.size() == 0) return {};
        int number = 0; //異或結果
        vector<int> res(2, 0);
        for(int i = 0; i < nums.size(); i++)
        {
            number ^= nums[i]; //全員異或得到兩個只出現一次元素的異或結果number,其中number的二進制值至少包含一個1,否則,結果就是0,表明兩元素相同,與題意不符
        }
        int pos = number & (-number); //按位與&,找到number最低位起第一個1的位置,,其中,-number表示number的相反數,即取反加1,例pos=(010&(110))=010,而與運算只有當兩者均為1是結果才為1,否則為0,即0 & 0 = 0, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1。
        for(int i = 0; i < nums.size(); i++) //以pos為標准分組,這個位置是1的數字,放到第一個數組里做異或運算,不是1的放到第二組。
        {
            if((nums[i] & pos) == pos) res[0] ^= nums[i]; //這個位置是1的時候,放入第一個數組做異或運算
            else
                res[1] ^= nums[i];
        }
        return res;
    }
};

參考文章

https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-by-leetcode/

https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/mian-shi-ti-56-shu-zu-zhong-shu-zi-chu-xian-de-ci-/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM