标签:
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
这道题的简单版本是除了一个数字之外,其他数字都出现了两次,这个很简单,将所有的数异或一遍就得到了那个数字。
如果不考虑空间复杂度的话,通过hash表统计的方法可以得到这两个数字;但如果空间复杂度要求为O(1),还是得参考异或的方法。
很明显,如果将数组中所有的数都异或一遍,那么得到结果就是剩下两个数字的异或结果,因为这是两个不同的数字,因此异或结果不可能为0。
那么这个结果的二进制表示中肯定存在某个二进制位为1,其中一个数在该位为0,另一个数在该位为1。
通过该位,我们可以将数组分成两类,一类在该位为0,一类在该位为1,将这两类数各自异或就可以得到两个只出现一次的数字。
#include <iostream> using namespace std; unsigned int FindFirstBitIs1(int num){ int indexBit=0; unsigned int count=1; while((num&count)==0){ count=count<<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(data==NULL || length<=1) return; int resultExclusiveOR=0; for(int i=0;i<length;i++){ resultExclusiveOR^=data[i]; } unsigned int indexOf1=FindFirstBitIs1(resultExclusiveOR); num1=0; num2=0; for(int i=0;i<length;i++){ if(IsBit1(data[i],indexOf1)) num1^=data[i]; else num2^=data[i]; } } int main() { int A[]={1,2,4,2,1,5,6,7,6,7}; int len=sizeof(A)/sizeof(A[0]); int num1=0; int num2=0; FindNumsAppearOnce(A,len,num1,num2); cout << num1 << " " << num2 << endl; return 0; }
http://www.nowcoder.com/books/coding-interviews/e02fdb54d7524710a7d664d082bb7811?rp=2
AC代码:
class Solution { public: bool IsBitOf1(int num,int k){ num=num>>k; return (num&1); } int findFirstBitOf1(int num){ int indexOf1=0; int count=1; while((num&count)==0){ count=count<<1; indexOf1++; } return indexOf1; } void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) { int length=data.size(); if(length<=1) return; int result=0; for(int i=0;i<length;i++) result^=data[i]; int indexOf1=findFirstBitOf1(result); *num1=0; *num2=0; for(int i=0;i<length;i++){ if(IsBitOf1(data[i],indexOf1)) *num1^=data[i]; else *num2^=data[i]; } } };
标签:
原文地址:http://www.cnblogs.com/AndyJee/p/4678826.html