一、一個數字出現一次,其餘數字出現兩次ios
兩個相同的數異或爲0,因此將數組裏的全部數依次異或,獲得的結果就是隻出現一次的數。windows
#include <iostream> using namespace std; int main() { int a[]={3,6,2,3,2,5,5}; int num=0; for(int i=0;i<7;i++) { num^=a[i]; } cout<<num<<endl; return 0; }
二、一個數字出現一次,其餘數字出現N次數組
經過觀察法,發現若是數字出現了n次,那麼每一bit位之和能夠被n整除。spa
#include <iostream> #include <string> using namespace std; int FindNumber(int a[], int n, int m) { int bits[32]; int i, j; // 累加數組中全部數字的二進制位 memset(bits, 0, 32 * sizeof(int)); for (i = 0; i < n; i++) for (j = 0; j < 32; j++) bits[j] += ((a[i] >> j) & 1); // 若是某位上的結果不能被整除,則確定目標數字在這一位上爲 int result = 0; for (j = 0; j < 32; j++) if (bits[j] % m != 0) result += (1 << j); return result; } int main() { int a[] = {2, 3, 1, 2, 3, 4, 1, 2, 3, 1}; //3表明其餘數字出現3次 cout<<FindNumber(a, 10, 3)<<endl; return 0; }
三、兩個數字出現一次,其餘數字出現兩次.net
和1的原理差很少,先是分別異或,獲得結果,確定不爲0。找到結果1所在的位置x,將原數組分爲兩部分,第一部分是x爲1的數的集合,第二部分是x爲0的數的集合。而後分別對這兩個數組異或,獲得這兩個出現一次的數。code
#include <iostream> #include <string> using namespace std; unsigned int FindFirstBitIs1(int num) { int indexBit=0; while(((num&1)==0)&&(indexBit<8*sizeof(int))) { num=num>>1; ++indexBit; } return indexBit; } bool IsBit1(int num,unsigned int indexBit) { num=num>>indexBit; return (num&1); } void FindNumsAppearance(int data[],int length,int *num1,int *num2) { if (data==NULL||length<2) { return; } int resultExclusiveOR=0; for (int i=0;i<length;i++) { resultExclusiveOR^=data[i]; } unsigned int indexof1=FindFirstBitIs1(resultExclusiveOR); *num1=*num2=0; for (int j=0;j<length;j++) { if (IsBit1(data[j],indexof1)) { *num1^=data[j]; } else { *num2^=data[j]; } } } int main() { int a[]={4,3,6,3,2,5,5}; int temp1,temp2; FindNumsAppearance(a,7,&temp1,&temp2); cout<<temp1<<"\t"<<temp2<<endl; return 0; }
參考:blog
http://blog.csdn.net/morewindows/article/details/12684497get