Python程序员面试算法宝典---解题总结: 第4章 数组 4.5 如何找出数组中出现奇数次的数

# -*- coding: utf-8 -*-

'''
Python程序员面试算法宝典---解题总结: 第4章 数组 4.5 如何找出数组中出现奇数次的数

题目:
数组中有N+2个数,其中,N个数出现了偶数次,2个数出现了奇数次(
这两个数不相等),请用O(1)的空间复杂度,找出这两个数。
注意:不需要知道具体位置,只需要找出这两个数。

分析:
应该还是一道关于异或的题目。只不过解法和之前的不同。
举例,假设数组为:
[1,2,3,3,2,1,4,5]
如果仅仅对整个数组的元素异或,那么结果就是那两个出现奇数次
的数的异或结果。
所以是否有办法能求出N个元素和其中一个出现奇数次的异或结果,
则就可以先求出一个出现奇数次的结果,另一个也会求出。
如何构造这样的场景:

关键:
1 书上解法
假设a.b分别是只出现一次的数字,
那么整个数组异或结果为result=a^b
其中找到result中某一位不为0.
那么再遍历一遍数组,找到数组中所有那一位也不为0的元素,
将元素之间进行异或,则必定得到其中一个只出现一次的数字,其值为num1
则另一个数字num2=result^num1

获取某一位为1可以使用将两个数的异或结果result不断向右移动来解决

2 我没想到
是因为忘记利用异或结果中某一位不为0,就可以寻找到所有
该位不为0的元素进行异或就可以得到其中一个数字


参考:
Python程序员面试算法宝典
'''

def findNums(array):
    if not array:
        return None, None
    result = 0
    for value in array:
        result ^= value
    position = 0
    tmpResult = result
    while tmpResult & 1 == 0:
        position += 1
        tmpResult = tmpResult >> 1
    # 寻找所有在position位置为1的数,异或得到某个出现一次的数
    num1 = 0
    for value in array:
        if ((value >> position) & 1) == 1:
            num1 ^= value
    num2 = result ^ num1
    return num1, num2


def process():
    array = [1, 2, 3, 3, 5, 6, 1, 2]
    num1, num2 = findNums(array)
    print num1
    print num2


if __name__ == "__main__":
    process()

 

你可能感兴趣的:(Python程序员面试算法宝典)