题目描述

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

知识点:异或

在python中,异或的符号^

print 8^2

#结果为10

首先 8 换为二进制表示 1000,而2用二进制表示为0010,异或规则为相同位上的数字一样,则为0(若1异或1为0),而1异或0为1。所以8^2为1010 ,结果为10

# -*- coding:utf-8 -*-
class Solution:
# 返回[a,b] 其中ab是出现一次的两个数字
def FindNumsAppearOnce(self, array):
# write code here
twonumXor = None
for num in array:
if twonumXor == None:
twonumXor = num
else:
twonumXor = twonumXor ^ num

count = 0
while twonumXor %2 == 0:
twonumXor = twonumXor >> 1
# twonumXor = twonumXor // 2 #方法二,取得1的位数
count += 1
mask = 1 << count

firstNum= None
secondNum = None

for num in array:
if mask & num == 0:
if firstNum == None:
firstNum = num
else:
firstNum = firstNum ^ num
else:
if secondNum == None:
secondNum = num
else:
secondNum = secondNum ^ num
return firstNum, secondNum

思路:
(1)两个相同的数字进行异或,结果一定是0,而0与其他不为0的数字进行异或,结果一定等于该数字
(2)数组中只有两个数字出现一次,将数组中的数字依次进行异或,最后的结果一定是这两个数字进行异或。如数组为[1,2,1,2,4,5,5,4,3,7],最后一定是3异或7
(3)3(二进制011)异或7(二进制111),异或的结果为100
(4)现在需要取得1所在位数,方法是将100%2 ,若100%2的结果为0,则将100 >> 1 ,重复操作,用一个变量count存放次数
(5) 然后mask = 1 << count ,此时也是100,用该mask对数组中的数依次取交集(如1(转二进制位001)&100结果为0,4&100结果为1),会把数组分为两部分,一部分交集的结果为0,一部分为1,而两个只出现1次数字,会分别出现在两个分离的数组中
(6)再对分离的数组依次取异或,最后就可以得到出现1次的数字
【剑指offer】数组中只出现一次的数字_整型