leetcode--python--只出现一次的数字

136. 只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
如果不限制空间复杂度和时间复杂度这道题挺好做,可以用无脑遍历,可以用哈希表,但是如果进行了限制,那就不好做了,下面这个通过异或的做法很新颖,特此记录。

1. 任何数和 00 做异或运算,结果仍然是原来的数,即 a \oplus 0=aa⊕0=a。2. 任何数和其自身做异或运算,结果是 00,即 a \oplus a=0a⊕a=0。3. 异或运算满足交换律和结合律,即 a \oplus b \oplus a=b \oplus a \oplus a=b \oplus (a \oplus a)=b \oplus0=ba⊕b⊕a=b⊕a⊕a=b⊕(a⊕a)=b⊕0=b。

通过上面的结论,因为题目中说明:只有一个是出现一次,其他都出现了2次,那么我们对数组依次进行异或得到的就是最后的只出现一次的值

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        return(reduce(lambda x, y: x^y, nums))#reduce是python的内置函数,
        #reduce接受一个函数和一个序列化数据作为参数,相当于把序列化的值交给函数处理,
        #一般reduce会和lambda函数一起使用

260. 只出现一次的数字 III

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
题解:为了使空间复杂度仍然为O(1),这里用到了异或操作和逻辑与操作,异或操作上面已经说过,逻辑与操作基本内容是:对于2个二进制数,只有相同位置上的值全为1则逻辑与后相应的位上仍然是1,例如0010&1110之后得到是0010.代码解释就看下面的注释代码。基本思想:

  1. 先将数组中的所有数字进行异或操作,得到xor,由于只有2个是单一的数字,其他的数字都是成对出现,所以最后的异或操作得到的结果实际上就相当于只出现一次的2个数的异或;
  2. 初始化ten为1,因为1的二进制的首位是1,其他位置上都是0,这样我们在进行移位的时候除了位置为1的位置与xor进行逻辑与操作后才有可能是1;
  3. 进行循环,知道xor与tem的逻辑与操作不为1,得到tem,目的是找到xor中那个位置上的值为1,如果xor位置上为1,证明原数组中的两个数量为1的数字的异或操作之后该位置为1;
  4. 找到这个位置为1的tem之后,遍历nums,将所有元素与tem进行逻辑与操作,进行分类,输出
class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        xor = 0
        num1 = 0
        num2 = 0
        for num in nums:
            xor = xor ^ num
        tem = 1
        while not tem & xor:
            tem <<= 1#移位操作,0001移位之后变为0010,0010移位变为0100
        for num in nums:
            if tem & num:
                num1 ^= num
            else:
                num2 ^= num
        return([num1, num2]) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值