【剑指Offer】40数组中只出现一次的数字

题目描述

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

时间限制:1秒;空间限制:32768K;本题知识点:数组

解题思路

思路一

利用一个字典类型的数据dict1来存储 数字--次数 对,然后循环字典查找出现次数为一的数字,输出结果。

# -*- coding:utf-8 -*-
class Solution:
    # 返回[a,b] 其中ab是出现一次的两个数字
    def FindNumsAppearOnce(self, array):
        # write code here
        dict1 = {} #新建字典用于存储 数字--个数
        for i in array:
            if str(i) in dict1: #将i转化为str型
                dict1[str(i)] += 1
            else:
                dict1[str(i)] = 1
        l = []
        for k in dict1.keys():
            if dict1[k] == 1:
                l.append(int(k)) #将i转化为int型
        return l

思路二

利用异或的思想来求解。一个数与它本身进行偶数次异或的结果为0,对原数组array全部数进行异或操作的结果是要求的ab两个数进行异或的结果。所以要做的就是通过某些操作将ab从异或结果中区分开啦,可以借助ab两数在二进制表达式下最右边的1的位置不同这个特点来区分,按照这个区别对原来的数组array分两组进行循环异或操作,便可以还原ab两个数。

Python程序:

# -*- coding:utf-8 -*-
class Solution:
    # 返回[a,b] 其中ab是出现一次的两个数字
    def FindNumsAppearOnce(self, array):
        # write code here
        result = 0
        for obj in array:
            result ^= obj    #异或运算,剩下的是a,b不同的两个数的异或结果
        index = self.find_1_index(result)
        num1 ,num2 = 0, 0
        for obj in array:
            if self.is_bit_1(obj, index):
                num1 ^= obj   #第N位为1的分为1组,这样能保证a,b分为两组
            else:
                num2 ^= obj
        return num1, num2
     
    # 找到右边第一个为1的位置,右移和位与运算
    def find_1_index(self, digit):
        index = 0
        while not digit & 1:
            digit >>= 1
            index += 1
        return index
    
    # 判断某个数字的右边的第n位是否为1
    def is_bit_1(self, digit, n):
        digit >>= n
        return digit & 1     # 位与运算

 

posted @ 2018-10-23 16:00  yucen  阅读(119)  评论(0编辑  收藏  举报