码迷,mamicode.com
首页 > 编程语言 > 详细

数组中只出现一次的数字

时间:2014-12-09 12:26:22      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:数组中出现一次的数字

题目:一个整型数组里除了两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!