美文网首页
寻找只出现过一次的数字

寻找只出现过一次的数字

作者: 小蛋子 | 来源:发表于2019-01-23 12:03 被阅读0次

    给定一个数组,只有一个数字出现过一次,其他均出现过两次,寻找这个只出现过一次的数
    说明:算法应该有线性时间复杂度,且尽可能不使用新的内存空间
    思路一:比较:首先对数组进行排序,数组长度是奇数,出现过两次的数字在相邻奇数位偶数位会同时出现。

    def find(L):
        L = sorted(L)
        for i in range(0, len(L), 2):
            if L[i] != L[i+1]:
                return L[i]
    
    find([2, 2, 4, 4, 1])
    # 1
    

    思路二:做差:排列后出现两次的数会在奇数位和偶数位各出现一次,奇数和与偶数和的差即为只出现过一次的数字。

    from functools import reduce
    
    
    def find_diff(L):
        L = sorted(L)
        sum_odd = reduce(lambda a,b: a+b, [L[i] for i in range(1, len(L), 2)])
        sum_even = reduce(lambda a,b: a+b, [L[i] for i in range(0, len(L), 2)])
        return sum_even - sum_odd
    
    find_diff([2, 2, 4, 4, 1])
    # 1
    

    思路三:hashset去重:利用hashset的特性,删除重复元素,最终剩余的即为只出现过一次的数字。

    def find_set(L):
        seen = set()
        for item in L:
            if item not in seen:
                seen.add(item)
            else:
                seen.remove(item)
        
        return seen.pop()
    
    find_set([2, 2, 3, 3, 1])
    # 1
    

    思路四:异或:根据异或的特点,相同的数字运算后结果为0,最终剩余的即为只出现过一次的。

    def find_xor(L):
        return reduce(lambda a, b: a^b, L)
    
    find_xor([1,2,1])
    # 2
    

    严格意义上只有思路四是正解。那如果现在有两个数字只出现过一次,请找出这两个数字。
    分析:异或运算中相同的数字最终结果为0,而此时有两个不同的数字只出现过一次,则两个数字不等,最终结果肯定不为0,且这个结果是两个只出现过一次的数字的异或的结果,所以,结果的二进制形式中至少有一位是1,即两个数的二进制形式至少有一位不同。此时我们按该位将数组分成两部分,则每部分都有切仅有一个只出现过一次的数字,然后对每部分分别进行查找只出现一次的数字即可。

    def find_tow_xor(L):
        res = reduce(lambda a, b: a^b, L)
        bitindex = 0
        for i in range(32):
            # 按位进行 且 运算,找到第一个是1的index
            if res>>i & 1:
                bitindex = i
                break
        
        L_0, L_1 = [], []
        for item in L:
            if item >> bitindex & 1:
                L_1.append(item)
            else:
                L_0.append(item)
        first = find_xor(L_0)
        sec = find_xor(L_1)
        return [first, sec]
    
    find_tow_xor([1,2, 1, 2, 11, 11, 22, 33])
    #[22, 33]
    

    相关文章

      网友评论

          本文标题:寻找只出现过一次的数字

          本文链接:https://www.haomeiwen.com/subject/cjkjjqtx.html