zoukankan      html  css  js  c++  java
  • (剑指Offer)面试题40:数组中只出现一次的数字

    题目:

    一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

    思路:

    这道题的简单版本是除了一个数字之外,其他数字都出现了两次,这个很简单,将所有的数异或一遍就得到了那个数字。

    如果不考虑空间复杂度的话,通过hash表统计的方法可以得到这两个数字;但如果空间复杂度要求为O(1),还是得参考异或的方法。

    很明显,如果将数组中所有的数都异或一遍,那么得到结果就是剩下两个数字的异或结果,因为这是两个不同的数字,因此异或结果不可能为0。

    那么这个结果的二进制表示中肯定存在某个二进制位为1,其中一个数在该位为0,另一个数在该位为1。

    通过该位,我们可以将数组分成两类,一类在该位为0,一类在该位为1,将这两类数各自异或就可以得到两个只出现一次的数字。

    代码:

    #include <iostream>
    
    using namespace std;
    
    unsigned int FindFirstBitIs1(int num){
        int indexBit=0;
        unsigned int count=1;
        while((num&count)==0){
            count=count<<1;
            indexBit++;
        }
        return indexBit;
    }
    
    bool IsBit1(int num,unsigned int indexBit){
        num=num>>indexBit;
        return (num&1);
    }
    
    void FindNumsAppearOnce(int data[],int length,int& num1,int &num2){
        if(data==NULL || length<=1)
            return;
    
        int resultExclusiveOR=0;
        for(int i=0;i<length;i++){
            resultExclusiveOR^=data[i];
        }
    
        unsigned int indexOf1=FindFirstBitIs1(resultExclusiveOR);
    
        num1=0;
        num2=0;
        for(int i=0;i<length;i++){
            if(IsBit1(data[i],indexOf1))
                num1^=data[i];
            else
                num2^=data[i];
        }
    }
    
    int main()
    {
        int A[]={1,2,4,2,1,5,6,7,6,7};
        int len=sizeof(A)/sizeof(A[0]);
        int num1=0;
        int num2=0;
        FindNumsAppearOnce(A,len,num1,num2);
        cout << num1 << " " << num2 << endl;
        return 0;
    }

    在线测试OJ:

    http://www.nowcoder.com/books/coding-interviews/e02fdb54d7524710a7d664d082bb7811?rp=2

    AC代码:

    class Solution {
    public:
        bool IsBitOf1(int num,int k){
            num=num>>k;
            return (num&1);
        }
    
        int findFirstBitOf1(int num){
            int indexOf1=0;
            int count=1;
            while((num&count)==0){
                count=count<<1;
                indexOf1++;
            }
            return indexOf1;
        }
    
        void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
    		int length=data.size();
            if(length<=1)
                return;
    
            int result=0;
            for(int i=0;i<length;i++)
                result^=data[i];
    
            int indexOf1=findFirstBitOf1(result);
    
            *num1=0;
            *num2=0;
            for(int i=0;i<length;i++){
                if(IsBitOf1(data[i],indexOf1))
                    *num1^=data[i];
                else
                    *num2^=data[i];
            }
        }
    };
    

      

  • 相关阅读:
    快速搞懂.NET 5/.NET Core应用程序的发布部署
    .NET 5 程序高级调试-WinDbg
    mmap出现 Permission denied
    Java int和integer有什么区别 (mybatis踩坑)
    NodeJS mysql timestamp 数据插入失败的问题
    mysql case when 用法
    postcss 源码解析以及运用
    rust漫游
    关于接口设计的思考--我们真的需要这么多入参吗
    详解apollo的设计与使用
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4678826.html
Copyright © 2011-2022 走看看