数组中只出现一次的数字升级版

来源:互联网 发布:微信收费数据共享 编辑:程序博客网 时间:2024/04/28 07:15
/*题目出处:《剑指offer——名企面试官精讲典型题目》P211题目:一个整型数组除了两个数字之外,其它的数字都出现了两次。请写程序找出这两个只出现一个的数字。要求时间复杂度是O(n),空间复杂度是O(1);*//*解题思路,这题是数组中除了一个数字外,其它的数字都出现两次的题目的变形,所以我们也应该从这个地方入手。如果只有一个数字,我们只需要用零去异或数组的所有数字,最后的结果就是那个落单的数字。那么这题的,最后异或所得的结果是 两个落单的数字异或的结果,首先,这个结果肯定不会是0,不然它们就相等,不符合题目要求。既然不是零,我们从这个数字中找到它的二进制数中的随便一位不是零的位数,那么就可以把这两个落单数字区分开了,就相当于是把这个数组分成的某个二进制位是否为1的两个数组。接着我们就可以按照一个数组所有数字都出现两次,只有一个数字出现一次的方法来做了。下面的解法是取异或结果的二进制数最右边的1的位置。*/#include<iostream>using namespace std;class TwoNumbersAppearOnce{public :TwoNumbersAppearOnce (){};~TwoNumbersAppearOnce(){};void FindNumsAppearOnce(int data[], int length, int *numOne, int *numTwo){if(data == NULL || length<2)return ;int i;int result = 0;for(i=0; i<length; ++i)result = result ^ data[i];int indexOf1 = FindFirstRightOf1(result);*numOne = 0;*numTwo = 0;for(i=0; i<length; ++i){if(isOne(data[i],indexOf1))*numOne = *numOne ^ data[i];else*numTwo = *numTwo ^ data[i];}}private:int FindFirstRightOf1(int result){int index = 0;while((result & 0x1)==0 && index<sizeof(int)*8){++index;result = result>>1;}return index;}bool isOne(int numOne , int index){numOne = numOne >>index;if((numOne & 0x1))return true;return false;}};int main(){TwoNumbersAppearOnce twoNumbersAppearOnce;int arr[8] = {2,2,1,3,4,4,5,5};int numOne;int numTwo;twoNumbersAppearOnce.FindNumsAppearOnce(arr,8, &numOne, &numTwo);cout<<numOne<<" "<<numTwo<<endl;return 0;}

0 0
原创粉丝点击