阅读目录

  • 题目描述
  • 思路与Python实现
  • 思路一
  • 思路二


题目描述

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

思路与Python实现

思路一

位运算 解法

  • 我们知道,两个相同的数 按位异或 会等于0,并且 异或 满足交换律,如下图:
  • 那么我们可以先依次对这个数组的每一个数,进行异或操作;那么结果就是:两个出现次数为1的数字的异或结果,而且它们的结果肯定不为0,也就是说在这个结果数字的二进制表示中至少就有一位为“1”,(如下图)接着就要用到这个特性!
  • 在结果数字中找到第一个为“1”的位的位置,记为第N位;然后让这个以1位最高位的二进制数依次和数组每一位数进行按位与操作;结果:以第N 位是不是1 为标准把原数组中的数字分成两个子数组,因为第N为异或结果为1的话,这两个数的第N为一定是一个为0一个为1,那么我们就以这个标准对原数组的数划分为两个子数组,第一个子数组中每个数字的第N 位都为1 ,而第二个子数组的每个数字的第N 位都为0 。那么在这两个子数组中依次异或,得到的两个结果就是出现次数为1的数字。

python 有个方法只能运行一次 python只执行一次_数据结构与算法


python 有个方法只能运行一次 python只执行一次_Python_02

class Solution:
    def FindNumsAppearOnce(self, array):
        if len(array) < 2:
            return None
        two_num_xor = None
        for num in array:
            if two_num_xor is None:
                two_num_xor = num
            else:
                two_num_xor = two_num_xor ^ num
		# 找出能将两个不同的数所在的领域分区的mask
        count = 0
        while two_num_xor % 2 == 0: # two_num_xor & 1 == 0 也行
            two_num_xor = two_num_xor >> 1 # two_num_xor>>=1
            count += 1
        mask = 1 << count
		# 然后在分别对两块区域进行按位异或操作,就能找出这两个不同的数
        first_num = None
        second_num = None
        for num in array:
            if mask & num == 0:
                if first_num is None:
                    first_num = num
                else:
                    first_num = first_num ^ num
            else:
                if second_num is None:
                    second_num = num
                else:
                    second_num = second_num ^ num
        return first_num, second_num
# 判断简写 因为任何数^0 都是本身
class Solution:
    def FindNumsAppearOnce(self, array):
        if len(array) < 2:
            return None
        two_num_xor = 0
        for num in array:
            two_num_xor = two_num_xor ^ num

        count = 0
        while two_num_xor & 1 == 0:
            two_num_xor >>= 1
            count += 1
        mask = 1 << count

        first_num = 0
        second_num = 0
        for num in array:
            if mask & num == 0:
                first_num = first_num ^ num
            else:
                second_num = second_num ^ num
        return first_num, second_num
思路二

哈希表 字典 做法

  • 利用字典,记录每个数字出现的次数,返回出现次数为1的数字,但是浪费空间
class Solution:
    def FindNumsAppearOnce(self, array):
        count = dict()
        # count = {}
        for i in array:
            if i not in count:
                count[i] = 0
            count[i] += 1
        result = []
        for key,val in count.items():
            if val == 1:
                result.append(key)
            else:
                continue
        return result
        
obj = Solution()
print(obj.FindNumsAppearOnce([1, 2, 1, 2, 3, 4, 5, 5, 4, 7]))