劍指Offer——(40)數組中只出現一次的數字

題目描述:

一個整型數組裏除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。

實現如下:

//關鍵點是使用異或位運算符
//相同的數字異或結果爲零
//如果數組中只有一個數字出現一次,那麼異或的遍歷這個數組,最後的結果就是那個數字
//如果此時變成有兩個數字都出現了一次,那還按照之前的辦法,最後的結果就是這兩個數字的異或值
//解決方法:
//將數組異或的遍歷,求其結果的第一個爲1的位數
//因爲這一位是兩個數字之間不同的位,即一箇中位,另一箇中爲0
//再一次遍歷數組,判斷所有的元素這一位是否爲1,並按此分爲兩組
//組內再將所有的元素異或,最終的值即爲只出現一次的數字
//因爲出現兩次的數字,都會被分到同一組,所以異或時就抵消了
class Solution 
{
public:
    unsigned int xorIndexResult(int xorResult)
    {
        unsigned int index = 0;
        //當位數小於32爲且此爲不爲1時,繼續計算
        while (index < 8 * sizeof(xorResult) && ((xorResult & 1) == 0))
        {
            xorResult = xorResult >> 1;
            ++index;
        }
        return index;
    }

    void FindNumsAppearOnce(vector<int> data, int* num1, int *num2) 
    {
        if (data.size() < 2)//防禦性動作
            return;

        int xorResult = 0;//記錄整個數組的異或結果
        for (int i = 0; i < data.size(); ++i)
            xorResult ^= data[i];

        //計算異或結果中,第一個值爲1的位數
        unsigned int xorIndex = xorIndexResult(xorResult);

        for (int j = 0; j < data.size(); ++j)
        {
            int tmp = data[j];
            tmp = tmp >> xorIndex;//計算所有元素此位的值,並進行分組
            if (tmp & 1)
                *num1 ^= data[j];//組內再進行異或計算
            else
                *num2 ^= data[j];
        }
    }
};
發佈了107 篇原創文章 · 獲贊 36 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章