1. 程式人生 > >陣列中只出現一次的兩個數字(百度面試題)

陣列中只出現一次的兩個數字(百度面試題)

題目要求:

在一個數組中,其餘數字都是成堆出現的,只有兩個數字出現了一次。儘快找到這兩個數字。

思路:

之前有過類似題,是一組陣列中只有一個數字出現了一次,其餘數字都是成對出現的。找到這個數字。這道題直接異或就可以得出結果。但是若陣列中有兩個只出現了一次的數字,再用異或得出的就是兩個只出現一次的數字異或的結果。即陣列若為{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;
}