劍指offer-找出數組中只出現一次的數字

/*******************************************************************
Copyright(c) 2016, Tyrone Li
All rights reserved.
*******************************************************************/
// 作者:TyroneLi
//
 
/*
Q:
    找出數組中只出現一次的數字:
        一個整型數組中除了兩個數字以外,其他的數字都出現了兩次,找出這兩個
        只出現一次的數字,要求時間複雜度是O(n),空間複雜度是O(1)。
S:
    1. 對於這樣的數組,只有一個數字出現了一次,其他的數字都出現了兩次,如何
       找出這個數字呢?我們可以從頭到尾遍歷這個數組,每個遍歷一個數字都做亦
       或操作,那麼根據亦或操作結果,最後得到的就是這個只出現一次的數字。對
       於兩個只出現一次,其他的數字都出現兩次的數組,考慮如何劃分數組使得劃
       分出每個子數組只包含出現一次的數字,其他的數字都出現了兩次?也是從頭
       到尾亦或遍歷數組,此時得到的結果是兩個只出現一次的不同的數字的亦或結
       果,則可以根據這個結果中的某一位爲是否爲1,把整個數組劃分成一個子數組
       這一位是1,另一個子數組這一位是0.
*/

#include <iostream>
#include <cstdio>
#include <cstdlib>

unsigned int findFirstDiffBitIndex(int num)
{
    int rstIndex = 0;
    while(((num & 1) == 0) && rstIndex < (8*sizeof(int)))
    {
        num >>= 1;
        ++rstIndex;
    }
    
    return rstIndex;
}

bool isBitOf1(int num, int index)
{
    if(index < 0)
        return false;
    num >>= index;
    return (num & 1);
}

void findTwoDiffNums(int*data, int length, int*num_1, int*num_2)
{
    if(data == nullptr || length < 2)
        return;
    
    int rstNumOfFirst = 0;
    for(int i = 0; i < length; ++i)
        rstNumOfFirst ^= data[i];
    
    unsigned int firstDiffBit1 = findFirstDiffBitIndex(rstNumOfFirst);
    // std::cout << "rstNumOfFirst : " << rstNumOfFirst << " firstDiffBit1 : " << firstDiffBit1 << std::endl;

    *num_1 = 0;
    *num_2 = 0;
    for(int i = 0; i < length; ++i)
    {
        if(isBitOf1(data[i], firstDiffBit1))
            (*num_1) ^= data[i];
        else
            (*num_2) ^= data[i];
        
    }
}

void test_1()
{
    std::cout << "Test 1" << std::endl;
    int data[] = {1,1,2,2,3,4,5,5};
    int num_1 = 0;
    int num_2 = 0;
    findTwoDiffNums(data, 8, &num_1, &num_2);
    std::cout << "Two result : 3 4, Get : " << num_1 << " " << num_2 << std::endl;
}

void test_2()
{
    std::cout << "Test 2" << std::endl;
    int data[] = {1,1,2,2,4,4,5,5};
    int num_1 = 0;
    int num_2 = 0;
    findTwoDiffNums(data, 8, &num_1, &num_2);
    std::cout << "Two result : 3 4, Get : " << num_1 << " " << num_2 << std::endl;
}

void test_3()
{
    std::cout << "Test 3" << std::endl;
    int data[] = {1,1,2,3};
    int num_1 = 0;
    int num_2 = 0;
    findTwoDiffNums(data, 4, &num_1, &num_2);
    std::cout << "Two result : 2 3, Get : " << num_1 << " " << num_2 << std::endl;
}

void test_findTwoDiffNums()
{
    test_1();
    test_2();
    test_3();
}

int main(int argc, char**argv)
{

    test_findTwoDiffNums();

    return 0;
}

 

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