code第一部分數組:第二十三題 奇數次中查找單獨出現一次的數

 

code第一部分數組:第二十三題 奇數次中查找單獨出現一次的數

 

Given an array of integers, every element appears three times except for one. Find that single one.
Note: Your algorithm should have a linear runtime complexity. Could you implement it without using
extra memory?
 
分析
解決方法1
由於每一個數出現3次,那麼這樣子分析,計算機存數假設是32位來存的,那麼
能夠創建一個32位的數字,來統計每一位上1出現的個數,咱們知道若是某一位上爲1的話,那麼若是該整數出現了三次,對3去餘爲0,咱們把每一個數的對應位都加起來對3取餘,最終剩下來的那個數就是單獨的數字。
 
解決方法2
 
用3個整數來表示INT的各位的出現次數狀況,one表示出現了1次,two表示出現了2次。當出現3次的時候該位清零。最後答案就是one的值。
- ones 表明第ith 位只出現一次的掩碼變量
- twos 表明第ith 位只出現兩次次的掩碼變量
- threes 表明第ith 位只出現三次的掩碼變量
 
解決方法3
咱們把數組中數字的每一位累加起來對3取餘,剩下的結果就是那個單獨數組該位上的數字,因爲咱們累加的過程都要對3取餘,那麼每一位上累加的過程就是0->1->2->0,換成二進制的表示爲00->01->10->00,那麼咱們能夠寫出對應關係:
 
00 (+) 1 = 01
 
01 (+) 1 = 10
 
10 (+) 1 = 00 ( mod 3)
 
那麼咱們用ab來表示開始的狀態,對於加1操做後,獲得的新狀態的ab的算法以下:
 
b = b xor r & ~a;
 
a = a xor r & ~b;
 
明白了上面的分析過程,就能寫出代碼以下;
#include <iostream>
using namespace std;


int singleNumber1(int a[],int n)
{
    int result=0;
    for (int i = 0; i < 32; i++)
    {
        int sum=0;
        for (int j = 0; j < n; j++)
        {
            sum+=(a[j]>>i)&1;
        }
        result|=(sum%3)<<i;
    }
    return result;
}

int singleNumber2(int A[], int n)
{
    int ones = 0, twos = 0, threes = 0;
    for (int i = 0; i < n; ++i)
    {
        twos |= (ones & A[i]);
        ones ^= A[i];
        threes = ~(ones & twos);
        ones &= threes;
        twos &= threes;
    }
    return ones;
}

int singleNumber3(int A[],int n)
{
    int a = 0;
    int b = 0;
    for (int i = 0; i < n; i++)
    {
        b = (b ^ A[i]) & ~a;
        a = (a ^ A[i]) & ~b;
    }
    return b;
}

int main()
{
    int a[10]={2,2,2,4,4,4,6,7,7,7};
    int ans=singleNumber1(a,10);
    cout<<"the ans is "<<ans<<endl;

    int ans2=singleNumber2(a,10);
    cout<<"the ans is "<<ans2<<endl;

    int ans3=singleNumber3(a,10);
    cout<<"the ans3 is "<<ans3<<endl;
    return 0;
}
相關文章
相關標籤/搜索