數組中僅出現一次的兩個數-異或

/**
題意:
一個整型數組裏除了兩個數字之外,其他的數字都出現了偶數次,
請寫程序找出這兩個出現一次的數字。
要求時間複雜度是O(n),空間複雜度是O(1).

解題思路:用異或操作
偶數個的異或起來爲0,所以最後異或的答案等於所求兩數異或和
這兩個數不一樣那麼異或結果一定至少有一位爲1。表示num1該位爲1,num2該位爲0。
將該位爲1的數全部異或起來,得到的結果是num1。
這是因爲除了num1之外,剩下的每個數(當然不包括num2)一定有偶數個。
同理將該位爲0的數全部異或起來,得到的結果是num2。
*/
#include <stdio.h>

unsigned int FindFirstBitIs1(int num)
{
      int indexBit = 0;
      while (((num & 1) == 0) && (indexBit < 32))
      {
            num = num >> 1;
            ++ indexBit;
      }
      return indexBit;
}

bool IsBit1(int num, unsigned int indexBit)
{
      num = num >> indexBit;
      return (num & 1);
}

void FindNumsAppearOnce(int data[], int length, int &num1, int &num2)
{
      if (length < 2)///即第一個和第二個數
            return;
      int resultExclusiveOR = 0;
      for (int i = 0; i < length; ++ i)
            resultExclusiveOR ^= data[i];

      ///找到第一位(2進制)是1的
      unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);
      num1 = num2 = 0;
      for (int j = 0; j < length; ++ j)
            if(IsBit1(data[j], indexOf1))///該位爲1的異或起來
                  num1 ^= data[j];
            else
                  num2 ^= data[j]; ///該位不爲1的異或起來
      }
}

int main()
{
    int n,i,x,y;
    int a[99999];
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        FindNumsAppearOnce(a,n,x,y);
        printf("%d\n",x+y);
    }
    return 0;
}

發佈了229 篇原創文章 · 獲贊 252 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章