《剑指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]

posted @ 2018-06-21 16:56  EEEEEcho  阅读(217)  评论(0编辑  收藏  举报