数组中只出现1次的数字

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;  
} 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值