剑指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]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值