陣列中只出現一次的兩個數字(百度面試題)
阿新 • • 發佈:2019-01-10
題目要求:
在一個數組中,其餘數字都是成堆出現的,只有兩個數字出現了一次。儘快找到這兩個數字。
思路:
之前有過類似題,是一組陣列中只有一個數字出現了一次,其餘數字都是成對出現的。找到這個數字。這道題直接異或就可以得出結果。但是若陣列中有兩個只出現了一次的數字,再用異或得出的就是兩個只出現一次的數字異或的結果。即陣列若為{1 2 3 3 2 1 4 5}結果就為4 5的異或結果,但若將4 5分的不同的組,再進行異或就能找到4 5。既然兩個數字不相同,那麼它們在某一位bit上肯定是不同的,那我們就可以根據這來進行分組。
int arr[]={1,2,3,3,2,1,4,5}
異或結果:4^5即0100^0101=0001即bit最低位就不同,所以整個陣列就可以根據最低位是1還是0來分
arr[0]=0001 第二組 arr[4]=0010 第一組
arr[1]=0010 第一組 arr[5]=0001第二組
arr[2]=0011 第二組 arr[6]=0100 第一組
arr[3]=0011 第二組 arr[7]=0101 第二組
這樣就將陣列分為兩組了,就轉換成一組陣列中只有一個數字出現了一次的問題。
直接進行異或就能分別找出只出現了一次的兩個數字。
#include<stdio.h> #include<assert.h> void FindTwoDifferent(int *arr,int len) { int fin=0; int i=0,j=0; int different1=0,different2=0; assert(arr); for(i=0;i<len;i++) { fin^=arr[i]; } while(i<32) { if(fin&1==1)//這兩個數字在32個bit上第i個位不同 break; fin>>=1; i++; j=i; } for(i=0;i<len;i++)//進行分組 { if(((arr[i]>>j)&1)==0) different1^=arr[i]; else different2^=arr[i]; } printf("Different Two:%d %d\n",different1,different2); } int main() { int arr[]={1,2,3,4,5,4,3,2,1,6}; int sz=sizeof(arr)/sizeof(arr[0]); FindTwoDifferent(arr,sz); return 0; }