我是靠谱客的博主 美好巨人,最近开发中收集的这篇文章主要介绍剑指Offer 56| LeetCode 136.只出现一次的数字(Python),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

LeetCode 136.只出现一次的数字
剑指Offer 56.数组中只出现一次的数字


LeetCode 136.只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
算法应该具有线性时间复杂度。 要求不使用额外空间来实现。

输入:[2,2,1]
输出:1
输入:[4,1,2,1,2]
输出:4

解题思路

哈希表

以元素值为key,元素出现的频次为value,构建字典,最后返回value == 1的key即可。
这个方法最大的缺点在于占用了O(n)的辅助空间,因此不满足题目要求。

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        dic = {}
        for i in range(len(nums)):
            if nums[i] not in dic:
                dic[nums[i]] = 1
            else:
                dic[nums[i]] += 1
        for key, value in dic.items():
            if value == 1:
                return key
        return None

位运算(异或)

利用位运算解决此题是较优的做法。
异或运算满足以下三个定律:

  • 交换律:a ^ b ^ c <=> a ^ c ^ b
  • 任何数于0异或为任何数 0 ^ n => n
  • 相同的数异或为0: n ^ n => 0

因此在题例中,4 ^ 1 ^ 2 ^ 1 ^ 2 = 1 ^ 1 ^ 2 ^ 2 ^ 4 = 0 ^ 2 ^ 2 ^ 4 = 0 ^ 0 ^ 4 = 4

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        a = 0
        for num in nums:
            a = a ^ num
        return a

剑指Offer 56.数组中只出现一次的数字

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


解题思路

与上题不同,上题只有一个数字出现一次,而这题是有两个数字出现一次。
继续考虑用位运算来处理,核心思想是将数组分为两半再进行上题的操作

  • 和上题一样,先将所有的数字进行异或,最后肯定得到两个只出现一次的数字异或的结果;
  • 对这个结果进行分析,找到其二进制为1的最低位,这个位上为1,说明两个数字的二进制在这个位上不相同,必然一个为1,一个为0;
  • 可以根据在此位上是否1,将数组里的所有数分为两半,每边都为若干对成对的数字加上一个只出现一次的数字;
  • 最后在两边各自按上题异或即可。
class Solution:
    # 返回[a,b] 其中ab是出现一次的两个数字

	# 判断此位上是否为1
    def isBit(self, num, index):
        num >>= index
        return num & 1
    
    def FindNumsAppearOnce(self, array):
        # write code here
            if not array: return 
    
            temp = 0
            for num in array:
                temp ^= num

            # 没有只出现一次的数字
            if temp == 0: return

            index = 0
          	# 找到为1的最低位
            while (temp&1) == 0:
                temp >>= 1
                index += 1

            a = b = 0
            # 分为两半,进行异或
            for num in array:
                if self.isBit(num, index):
                    a ^= num
                else:
                    b ^= num

            return [a,b]

2019.7.15 补充剑指Offer部分

最后

以上就是美好巨人为你收集整理的剑指Offer 56| LeetCode 136.只出现一次的数字(Python)的全部内容,希望文章能够帮你解决剑指Offer 56| LeetCode 136.只出现一次的数字(Python)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部