1.一个整型数组里除了1/2/3个数字之外,其它的数字都出现了2次。请写程序找出这1/2/3个只出现1次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
1个数字:
#include<iostream>
using namespace std;
int FindOneNumberAppearOnce(int data[],int n)
{
int i,result=0;
for(i=0;i<n;i++)result^=data[i];
return result;
}
int main()
{
int data[7]={2,4,3,3,2,5,5};
cout<<FindOneNumberAppearOnce(data,7)<<endl;
return 0;
}
2个数字:
#include<iostream>
using namespace std;
//寻找num的二进制表示的最后一位1的位置
int FindLastBit1(int num)
{
int index=0;
while(!(num&1)&&(index<8*sizeof(int)))
{
num>>=1;
++index;
}
return index;
}
//判断num的二进制表示的第index位是否为1
bool IsBit1(int num,int index)
{
num>>=index;
return num&1;
}
void FindTwoNumbersAppearOnce(int data[],int n,int &first,int &second)
{
int i,result=0,index;
for(i=0;i<n;i++)result^=data[i];
index=FindLastBit1(result);
first=0,second=0;
for(i=0;i<n;i++)
{
if(IsBit1(data[i],index))first^=data[i];
else second^=data[i];
}
}
int main()
{
int data[8]={2,4,3,6,3,2,5,5},a,b;
FindTwoNumbersAppearOnce(data,8,a,b);
cout<<a<<' '<<b<<endl;
return 0;
}
3个数字:
#include<iostream>
using namespace std;
//只保留num的二进制表示的最后一位1,其它位变成0
int LastBit1(int num)
{
return num&~(num-1);
}
int FindLastBit1(int num)
{
int index=0;
while(!(num&1)&&(index<8*sizeof(int)))
{
num>>=1;
++index;
}
return index;
}
bool IsBit1(int num,int index)
{
num>>=index;
return num&1;
}
void FindTwoNumbersAppearOnce(int data[],int n,int &first,int &second)
{
int i,result=0,index;
for(i=0;i<n;i++)result^=data[i];
index=FindLastBit1(result);
first=0,second=0;
for(i=0;i<n;i++)
{
if(IsBit1(data[i],index))first^=data[i];
else second^=data[i];
}
}
void FindThreeNumbersAppearOnce(int data[],int n,int &first,int &second,int &third)
{
int i,result=0,flags=0;
for(i=0;i<n;i++)result^=data[i];
for(i=0;i<n;i++)flags^=LastBit1(result^data[i]);
flags=LastBit1(flags);
first=0;
for(i=0;i<n;i++)
{
if(LastBit1(result^data[i])==flags)first^=data[i];
}
for(i=0;i<n;i++)
{
if(data[i]==first)
{
int temp=data[i];
data[i]=data[n-1];
data[n-1]=temp;
break;
}
}
FindTwoNumbersAppearOnce(data,n-1,second,third);
}
int main()
{
int data[9]={2,4,3,6,3,2,5,5,1};
int a,b,c;
FindThreeNumbersAppearOnce(data,9,a,b,c);
cout<<a<<' '<<b<<' '<<c<<endl;
return 0;
}
2.一个整型数组里除了1个数字之外,其它的数字都出现了N(N>=2)次。请写程序找出这1个只出现1次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
如果N为偶数,直接异或即可,下面考虑N为奇数。
#include<iostream>
using namespace std;
int FindOneNumbersAppearOnce(int data[],int n)
{
int bits[32]={0},i,j,result=0;
for(i=0;i<n;++i)
{
for(j=0;j<32;++j)bits[j]+=(data[i]>>j)&1;
}
for(j=0;j<32;++j)
{
if(bits[j]%3)result+=1<<j;
}
return result;
}
int main()
{
int data[10]={2,3,1,2,3,4,1,2,3,1};
cout<<FindOneNumbersAppearOnce(data,10)<<endl;
return 0;
}