《剑指offer》--- 数组中只出现一次的数字
本文算法使用python3实现
1. 问题
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
时间限制:1s;空间限制:32768K
2 思路描述
方法一:从头到尾遍历数组,如果使用count()进行判断,若出现次数为1,添加到结果中。
方法二:创建一个set()集合,从头到尾遍历数组,若数组中的数字已存在于set()集合中,则从set()中删除该数字,否则添加到set()中。最终set()中剩余的即为所求结果。
方法三:利用异或运算进行。当两个数字相同时,异或的结果为0。若一个数组,除了一个数字只出现一次,其它数字都出现过两次,那么这个数组从头至尾做异或运算,最后的结果即为这个只出现了一次的数字。于是我们就可以思考,如果把数组分成两部分,每个部分仅包含一个只出现一次的数字,那么分别对这两个部分进行异或,异或出来的结果就是所求两个数字。
如何将数组分成两部分呢?先将整个数组进行异或,异或的结果为两个只出现一次数字的异或结果。将其二进制的从右至左的第一个“1”作为划分条件,当数组数字的二进制在该为为“1”时划分到数组一中,否则划分到数组二中;对于二进制位数小于第一个“1”所在的位置时,划分到数组一种。
3 程序代码:
(1)方法一
class Solution:
def FindNumsAppearOnce(self, array):
once = []
for num in array:
if array.count(num) == 1:
once.append(num)
return once
def FindNumsAppearOnce(self, array):
if array == []:
return []
(2)方法二
class Solution:
def FindNumsAppearOnce(self, array):
tmp = set()
for a in array:
if a in tmp:
tmp.remove(a)
else:
tmp.add(a)
return list(tmp)
(3)方法三
class Solution:
def FindNumsAppearOnce(self, array):
if array == []:
return []
res = 0
list1 = []
list2 = []
for num in array:
res = res^num
tmp = bin(res).replace('0b','')
if '1' in tmp:
idx = tmp[::-1].index('1')
for num in array:
if idx >= len(bin(num).replace('0b','')):
list1.append(num)
elif bin(num).replace('0b','')[::-1][idx] != '1':
list1.append(num)
else:
list2.append(num)
tmp1 = 0
tmp2 = 0
print(list1)
print(list2)
for i in list1:
tmp1 = tmp1^i
for j in list2:
tmp2 = tmp2^j
return [tmp1, tmp2]