标签:数组中出现一次的数字
题目:一个整型数组里除了两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度为O(1)。
分析:由于时间复杂度和空间复杂度的限制,不可能用多次遍历数组方法和辅助数组的方法。因此问题比较难以下手。现在考虑如果只有一个数字出现了一次的情况,如果只有一个数字出现了一次,而其他数字都出现了两次,那么,我们可以将数组所有数字进行异或运算,那么最终结果就是这个数字。现在是两个数字,我们需要想办法将这个数组分成量个子数组,儿这两个子数组中分别包含这两个要求的数字,且其他数字都是成对出现,那么将两个子数组分别异或就得到了这两个数。如何分割数组呢?我们先将所有数字异或,得到一个非零的数字,就是这两个数字的异或,所以这两个数字的异或的二进制数中肯定有一位是1,我们根据这个二进制数中第一位为1的位置,将数组所有数字的二进制根据这个位置是否为1分成两个子数组。则这两个数分别被分到了这两个子数组中,且其他数字都是成对出现的。再将这两个数组分别异或就得到了这两个数字。实现如下:
void FindNumsAppearOnce(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]; } } 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); }
本文出自 “仙路千叠惊尘梦” 博客,请务必保留此出处http://secondscript.blog.51cto.com/9370042/1587794
标签:数组中出现一次的数字
原文地址:http://secondscript.blog.51cto.com/9370042/1587794