题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
# -*- coding: utf-8 -*-
# @Time : 2019-10-08 12:02
# @Author : Jayce Wong
# @ProjectName : job
# @FileName : findNumsAppearOnce.py
# @Blog : http://blog.51cto.com/jayce1111
# @Github : https://github.com/SysuJayce
class Solution:
"""
题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
# 返回[a,b] 其中ab是出现一次的两个数字
"""
def FindNumsAppearOnce(self, array):
"""
思路:我们已知两个相同的数做异或得到0,那么将数组中所有数字做异或后,如果这个数组中只有
一个数字只出现一次,那么异或的结果就是那个只出现一次的数字。
如果数组中有2个数字只出现一次,那么异或的结果就是那两个只出现一次的数字的异或。
在我们得到了异或结果之后,可以按照异或结果对数组进行划分,然后在划分后的2个子数组中分别
异或就可以得到该子数组中只出现一次的数字。
例如:
[1, 1, 2, 2, 3, 3, 4, 5]
那么对所有数字异或得到001(二进制表示)
那么就按照这个异或结果,找到为1的位的下标(这里随便找一个为1的就行,因为a和b在这一位肯定
不一样),然后按照该位是否为1对原数组进行划分
这里我们只有一位是1,所以划分得到[1, 1, 3, 3, 5], [2, 2, 4]
然后在子数组中做异或运算,得到5, 4。这两个数字就是我们要的
"""
if not array or len(array) < 2:
return []
# 先求出原数组的异或结果
temp = 0
for num in array:
temp ^= num
# 找出一位为1的下标
idx = 0
while temp & 1 != 1:
temp >>= 1
idx += 1
# 按照idx是否为1对原数组进行划分,分别异或,得到a和b
a = b = 0
for num in array:
if (num >> idx) & 1 == 1:
a ^= num
else:
b ^= num
return [a, b]