• 面试题1:落单的数


    题目来源:微信公众平台九章算法。因为九章算法仅仅给出了算法,并没有给出源码,这里笔者依据自己的能力给出了源码。当然可能会有非常多不足。希望大家不吝不吝赐教。                                             -——— 肖然

    题目描写叙述:

    有2n+1个数。当中2n个数两两成对,1个数落单,找出这个数。要求O(n)的时间复杂度,O(1)的空间复杂度。进阶问题:假设有2n+2个数,当中有2个数落单,该怎么办?

    题目分析:

    异或的性质,对于随意a,a^a=0; a^0=a;依据这两条性质能够写出下列代码。


    初阶:将2n+1个数异或起来,同样的数会抵消,异或的答案就是要找的数。


    进阶:如果两个不同的数是a和b。而且a!=b,将2n+2个数异或起来就会得到c=a xor b,而且c不等于0。

    因此在c的二进制位中找到一个为1的位,可判断在这位上a和b分别为0和1。因此将2n+2个数分为该位位0的组和该位为1的组,两组中各自会包括2n’+1个数和2n’’+1个数,用初阶的算法就可以解决。


    源码:
    /**
     *九章算法面试题一、落单的数
     *异或的简单应用
     *异或的性质: a^a=0; a^0=a;
     */
    #include<iostream>
    #include<cstdio>
    using namespace std;
    int a[10000],b[10000];
    int ans,ans0,ans1;
    int LuoDan1(int n,int *a){//初阶问题,给出2*n+1个数,仅仅有一个是单个的,求这个数
        ans=0;
        for(int i=0;i<2*n+1;i++){
            ans^=a[i];
        }
        return ans;
    }
    int Judge(int n,int k){//推断第k位(从右到左)是否为1
        int i=1;
        while(i++<k-1) n>>=1;//向左移位k-1位
        if(n>>1==1) return 1;//第k位是1,返回1
        else return 0;
    }

    int LuoDan2(int n,int *a){//初阶问题,给出2*n+2个数,仅仅有两个是单个的,求这两个数
        ans=0;
        for(int i=0;i<2*n+2;i++){
            ans^=a[i];
        }
        int k=1;
        //cout<<ans<<endl;
        while(ans>0){//找到最低位的1
            if((ans&1)==1) break;
            ++k;
            ans>>=1;
        }
        ans0=ans1=0;
        for(int i=0;i<2*n+2;i++){
            if(Judge(a[i],k)){//第k位为1
                ans1^=a[i];
            }
            else ans0^=a[i];
        }
        //cout<<ans0<<" "<<ans1<<endl;
        return ans;
    }
    int main()
    {
        int n;
        while(cin>>n){
            int ans=0;
            for(int i=0;i<2*n+1;i++){
                cin>>a[i];
                //ans^=a[i];
            }
            cout<<LuoDan1(n,a)<<endl;
            for(int i=0;i<2*n+2;i++){
                cin>>b[i];
            }
            //cout<<ans<<endl;
            LuoDan2(n,b);
            cout<<ans0<<" "<<ans1<<endl;
        }
        return 0;
    }




  • 相关阅读:
    字符串倒序
    字符串反转问题
    linux系统性能分析
    操作系统基础知识
    两个数组a[N],b[N],其中A[N]的各个元素值已知,现给b[i]赋值,b[i] = a[0]*a[1]*a[2]…*a[N-1]/a[i];
    用加法模拟乘法
    2015年最新中国知网CNKI免费账号直接入口
    nginx模块开发(18)—日志分析
    nginx基本配置
    三层架构和MVC
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5197178.html
Copyright © 2020-2023  润新知