常见面试算法题:N个数中寻找仅出现过1次的数

来源:互联网 发布:行程助手软件 编辑:程序博客网 时间:2024/06/10 00:53

最近有面试他人,感觉温习温习这些算法题还蛮有意思,因此单开一个系列进行回顾和探讨。

第一个算法题最原始的问题版本是:现有N个数,其中有1个数只出现了一次,其它数均出现了2次,要求找到这个仅出现过1次的数。要求空间复杂度为O(1)。

  • 求解思路:异或法
    根据异或的计算规则,两个相同的数做异或操作后结果为0,两个不同的数做异或操作结果绝对不为0,而任何数与0异或结果仍为自身。因此将给定的N个数从前至后依次做异或操作后,所有重复的数两两异或后均为0,只剩下那个只出现了1次的词,即为异或操作最后的结果。算法空间复杂度O(1),时间复杂度O(N)。

进化的问题版本是:现有N个数,其中有2个数只出现了1次,其它数均出现了2次,要求找到这两个仅出现过1次的数。要求空间复杂度为O(1)。

  • 求解思路:数组划分+异或法
    为保证算法空间复杂度为O(1),仍只能采用异或法的思路。但是原始版本算法直接应用存在的问题是,所有数做异或后得到的仅有一个数C,这个数就是那两个只出现了1次的数,记为A和B的异或结果。必须采用一定的策略使得问题又回复到原始版本,方可在O(1)的空间复杂度里解决,而策略的关键则是要将A和B划分到两个分开的子数组中。具体的策略为:由于C为A和B的异或操作结果,因此在C的二进制表达中,值为1的位置即为A和B的二进制位上取值不同的位置。只需要任意取其中的1位对原始的N的数组做划分,即能将A和B分到不同的子数组中。当这一步完成后,采用异或法对两个子数组分别做一遍异或操作即可得到A和B。空间复杂度O(1),时间复杂度仍为O(Nk),k为系统整型长度。

留下一个问题,如果将第二个版本的问题再次升级,在N个数中是有3个数仅出现了1次,其它数则均出现了2次,要如何找到这3个数呢?还能在O(1)的空间复杂度里解决么?

0 0