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

猜你喜欢

转载自www.cnblogs.com/lliuye/p/9209918.html