劍指offer 面試題56 數組中數字出現的次數

問題1:數組中只出現一次的兩個數字

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

2 <= nums <= 10000

思路:異或

首先,對數組的每個數字依次進行異或,得到異或後的結果value。

然後,記value最右邊第一位爲1的位爲i,依據第i位爲1/0將數組分爲兩組。

最後,在每個子數組中,依次進行異或,異或後的結果爲兩個只出現一次的數字。

代碼:

class Solution {
public:
    int FindFirstBisIs1(int num)
    {
        int index=0;
        while(((num&1)==0)&&(index<8*sizeof(int)))
        {
            num=num>>1;
            ++index;
        }
        return index;
    }
    bool IsBit1(int num,int index)
    {
        num=num>>index;
        return (num&1);
    }
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        if(data.empty())
            return;
        int resOR=0;
        int len=data.size();
        for(int i=0;i<len;++i)
        {
            resOR^=data[i];
        }
        int index=FindFirstBisIs1(resOR);
        *num1=*num2=0;
        for(int j=0;j<len;++j)
        {
            if(IsBit1(data[j],index))
                *num1^=data[j];
            else
                *num2^=data[j];
        }
    }
};

複雜度分析:時間複雜度是O(n),空間複雜度是O(1)。

問題2:數組中唯一隻出現一次的數字

在一個數組 nums 中除一個數字只出現一次之外,其他數字都出現了三次。請找出那個只出現一次的數字。

1 <= nums.length <= 10000
1 <= nums[i] < 2^31

思路:位運算

如果一個數字出現三次,那麼它的二進制表示的每一個也出現三次,把二進制表示的每一位加起來,能被三整除。

某一位不能被整除的說明要求的數字在該位上爲1,否則爲0.

代碼:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int bitSum[32]={0};
        int len=nums.size();
        for(int i=0;i<len;++i)
        {
            unsigned int bitMask=1;  // int 不能被右移
            for(int j=31;j>=0;--j)
            {
                int bit=nums[i]&bitMask;
                if(bit!=0)
                    bitSum[j]+=1;
                bitMask=bitMask<<1;
            }
        }
        int res=0;
        for(int i=0;i<32;++i)
        {
            res=res<<1;
            res+=bitSum[i]%3;
        }
        return res;
    }
};

複雜度分析:時間複雜度是O(n),空間複雜度是O(1)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章