寻找丢失的数字(二)

如果你还没有看过上一篇文章,请先移步看问题描述。

扩展问题二:至多扫描一遍序列,求出丢失的两个数字。  

不管用什么方法,可以肯定的是我们至少需要扫描一遍序列。

因为只能扫描一遍,所以先求出 a XOR b,再根据结果分类的方法就不适用了。

既然我们不能根据某一位分类,那我们能否对所有位进行分类呢?比如,int是32位,我们可以对每一位都分成两类分别异或。

我们还要记录每一位上1出现的次数,实际上,只需要记录1出现奇数次还是偶数次就够了。 

如果某一位上1出现奇数次,那么我们就知道 a 和 b 在此位上的比特不同。从而利用前面分类异或的结果就直接得出答案。

Python 代码:

def find_missing_2_numbers_v2(sequence, n):
    """ returns the missing two numbers of sequence, which is supposed
    to be a permutation of {1,..,n} with two numbers missing.
    An one-pass algorithm.
    
"""
    xors = [[0 for i in xrange(2)] for j in xrange(32)]
    counts = [0 for i in xrange(32)]
    for i in xrange(1, n + 1):
        for k in xrange(32):
            t = 1 & (i >> k)
            xors[k][t] ^= i
            counts[k] ^= t
    for e in sequence:
        for k in xrange(32):
            t = 1 & (e >> k)
            xors[k][t] ^= e
            counts[k] ^= t
    a, b = 0, 0
    for k in xrange(32):
        if counts[k]:
            a, b = xors[k][0], xors[k][1]
            break

    return a, b 

 

扩展问题三:如果有三个数字丢失了呢?

其实上面的方法稍加修改就可以解决此问,具体实现留给读者。有道类似题目http://yzfy.org/dis/listpost.php?tid=1009 可以用来测试你的算法~

posted @ 2012-04-24 16:53  shilcare  阅读(1402)  评论(1编辑  收藏  举报