剑指Offer:数组中只出现一次的数字

63 篇文章 0 订阅
41 篇文章 0 订阅

题目:
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
思路:
1、两次for循环,O(n2)
2、哈希map,O(N),但是有额外空间
3、从头到尾一次异或数组中的每一个数字,那最终结果就是两个只出现一次的数的异或。结果肯定不为0,在结果数组中找到第一个为1的位的位置,记为第n位。以第n位是不是1为标准把元数组中的数字分成两个子数组,第一个子数组中每个数字的第n位都是1,而第二个子数组中每个数字的第n位都是0,两个只出现一次的数会被分在两个子数组内,分别异或即可得到结果。
方法三代码:

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) 
    {
        int iResultOr = 0;
        for(int i=0; i<data.size(); ++i)
        {
            iResultOr ^= data[i];
        }
        
        int FirstNotZero = FindFirstNotZero(iResultOr);
        
        *num1 = *num2 = 0;
        for(int i=0; i<data.size(); ++i)
        {
            if(IfBitOne(data[i], FirstNotZero))
            {
                *num1 ^= data[i];
            }
            else
            {
                *num2 ^= data[i];
            }
        }
    }
        
    bool IfBitOne(int num, int FirstNotZero)
    {
         num = num >>  (FirstNotZero  - 1);  
         //这里&一定要加括号
         return 1 == (num&1);
    }
        
    int FindFirstNotZero(int num)
    {
        int FirstNotZero = 1;
        //这里&一定要加括号
        while(0 == (num&1))
        {
            num = num >> 1;
            ++FirstNotZero;
        }
        return  FirstNotZero;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值