leetcode -- single number 只出现一次的数字

136

给定一个整数数组,除了某个元素外其余元素均出现两次。请找出这个只出现一次的元素。

备注:
你的算法应该是一个线性时间复杂度。 你可以不用额外空间来实现它吗?

解析:不能用额外空间,所以哈希表也就是字典是不能用了,那就只能位操作了,用异或运算,a^a=0,所以出现两次的数都就消除了,最后剩下那个只出现一次的数

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        rst = nums[0]
        for i in range(1,len(nums)):
            rst = rst ^ nums[i]
        return rst

137

给定一个整型数组,除了一个元素只出现一次外,其余每个元素都出现了三次。求出那个只出现一次的数。

注意:
你的算法应该具有线性的时间复杂度。你能否不使用额外的内存来实现?

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        ones, twos = 0, 0
        for i in range(len(nums)):
            ones = (ones ^ nums[i]) & (~twos)
            twos = (twos ^ nums[i]) & (~ones)
        return ones

260

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其他所有元素均出现两次。 找出只出现一次的那两个元素。

示例:
给定 nums = [1, 2, 1, 3, 2, 5], 返回 [3, 5].

注意:
结果的顺序并不重要,对于上面的例子 [5, 3] 也是正确答案。
你的算法应该具有线性复杂度,你能否仅使用恒定的空间复杂度来实现它?

解析:这里需要解释下异或运算的含义,异或就是找两个数不相同的位,我们很容易通过一次循环找到两个数的异或结果c,有了c怎么找到这两个数呢,首先找到他们第一个不相同的位,即通过firstBit = rst_xor & ~(rst_xor - 1)找到最低的不相同位,然后让所有在这一位上取值为1的数异或,那么就获得其中一个数a,有了a和c,那么b就很容易获得了
c = a^b
a = c^b
b = c^a

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        rst_xor = nums[0]
        rst = [0,0]
        for i in range(1,len(nums)):
            rst_xor = rst_xor ^ nums[i]
        firstBit = rst_xor & ~(rst_xor - 1)  

        for i in range(len(nums)):
            if(nums[i] & firstBit):
                rst[0] = rst[0] ^ nums[i];
        rst[1] = rst_xor ^ rst[0]
        return rst 

增加题目

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

解析:假设这三个数是a b c,那么通过异或运算可以得到三个数的异或值,即d=a^b^c,所以题目等价于:假设一个数组中有3个不同的数字 a、b 和 c,已知 aXORbXORc = a ^ b ^ c ,求 a、b 和 c 。
根据异或特性可以得知:
(aXORbXORc ^ a) ^ (aXORbXORc ^ b) ^ (aXORbXORc ^ c) = 0
若令X=aXORbXORc ^ a Y=aXORbXORc ^ b Z=aXORbXORc ^ c,
X^Y^Z=0,那么X Y Z 三个数中找到低位中第一个不为0的位置,在这个位置上X Y Z有三种可能:111、010、101(000不用考虑,因为找的就是不为0的位置),而X^Y^Z=0,所以只可能是101,也就是两个相同一个不同,那么可以通过异或获得那个不同的数,也就是如果我们获取到这三个数的低位第一个为1的位置后,进行异或,并令低位第一位为1的位置为firstBit ,就可以找到三个中不同的那个,即遍历这三个数X Y Z,如果发现某个数异或 aXORbXORc 等于 firstBit ,这个数就是不为0的最低位不同的那个数,令这个数为a,找到它之后b^c=aXORbXORc ^ a,再根据上一题的方法就能找到b c

class Solution(object):
    def getFirstBit(self,num):
        return num & ~(num-1)

    def singleThreeNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        abc = nums[0]
        bc = 0
        rst = [0,0,0]
        firstBit = 0
        for i in range(1,len(nums)):
            abc = abc ^ nums[i]

        for i in range(len(nums)):
            firstBit = firstBit ^ Solution().getFirstBit(abc ^ nums[i])
        firstBit = Solution().getFirstBit(firstBit)

        for i in range(len(nums)):
            if(Solution().getFirstBit(abc ^ nums[i]) == firstBit):
                rst[0] = rst[0] ^ nums[i]

        bc = abc ^ rst[0]
        secondBit = bc & ~(bc - 1)  

        for i in range(len(nums)):
            if(nums[i] & secondBit):
                rst[1] = rst[1] ^ nums[i];
        rst[2] = bc ^ rst[1]        
        return rst 

参考:
https://blog.csdn.net/su20145104009/article/details/51295067

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值