zoukankan      html  css  js  c++  java
  • 成对出现的一组数字,找出两个只出现一次的数字

      记得,当时是去多看面试,感觉,比百度的实习生面试松一点,因为好多算法只是让我说思路,不用写。  

      二面记得最清晰的问题,就是给很多的一组数,所有数都是成对出现的,只有一个数只出现了一次,面试官问我,怎么弄。我很开心的说,见过这题,异或,最后的结果就是那个只出现一次的数。然后,面试官犹豫了一下,又问,如果是出现两个只出现了一次的数呢(估计是在想,我是不是也知道答案,有没有必要问)。我确认了下时间复杂度要求,要求时间复杂度是O(n),空间复杂度是O(1)我才不会告诉你我当时没弄出来。。。。。

      回来查了查,发现其实也不是太难:

        (1)首先,只有一个只出现一次的数,直接异或,所有相同的数都会被抵消(异或运算中,相同位置值相等的结果为0,就是说所有成对出现的都会最终成为0),最后的结果自然是那个落单的数了;

        (2)再来讨论稍微复杂点的那个,如果是有两个互不相同的数,我们可以把他分成两个段,段名分别为A,B。这里为了解释方便,给出10个数,分别为a,a,b,b,c,c,d,d,e,f;

          现在我们知道,只要A段和B段能满足上面的(1)所说的情形,即两个不同的数(e,f分别在A,B段内)分别在不同的段内,其他的数成对出现在相同的段内,就可以仿照(1)得到结果。举个例子A(a,a,b,b,e);B(c,c,d,d,f);

          是不是觉得很难分呢?怎么才能按照上面的形式分开成为A,B呢?别急,注意咯,我上面说的是其他数成对出现,并不是一定要对半分,也可以是A(a,a,b,b,c,c,d,d,e);B(f);或者A(a,a,b,b,c,c,e);B(d,d,f);是不是有点头绪了?没有?别紧张,往下看,快搞定了

          我们先来想想如何分e,f。首先,他们本身不相等,所以e^f的值一定不为0,也就是说,e^f的值转换成2进制,一定至少有一个1出现。好的,我们从右向左找第一次出现1的位置,将所有数中,这个位置是1的放进A,是0的放进B。OK,完全符合我们对AB段的要求,再从A,B中分别异或找出e,f不是问题!

    作者:FreeAquar
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    【转载】爸妈,求你们不要这么懂事
    【Selenium】各种方式在选择的时候应该怎么选择
    java动态绑定与静态绑定【转】
    java 字符串池【转】
    【转】java中PriorityQueue优先级队列使用方法
    【转】程序员的出路之一
    关于现在,关于未来
    计算机网络实验(router_sim)工具
    MIT算法导论课程
    最大间隙问题
  • 原文地址:https://www.cnblogs.com/FreeAquar/p/2789433.html
Copyright © 2011-2022 走看看