成对出现的一组数字,找出两个只出现一次的数字

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

  二面记得最清晰的问题,就是给很多的一组数,所有数都是成对出现的,只有一个数只出现了一次,面试官问我,怎么弄。我很开心的说,见过这题,异或,最后的结果就是那个只出现一次的数。然后,面试官犹豫了一下,又问,如果是出现两个只出现了一次的数呢(估计是在想,我是不是也知道答案,有没有必要问)。我确认了下时间复杂度要求,要求时间复杂度是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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/FreeAquar/p/2789433.html