Leetcode 260. Single Number Ⅲ

首先有这样一个问题:如果有一个数组,除了一个数字出现了一次,其余数字都出现了两次,求这个出现了一次的数字。

这个问题的解法只需要将数组中所有的数字都进行异或,最后的结果就是只出现了一次的数字。原因是任何两个相同的数字异或结果都为0,并且异或满足交换律。

而对于数组中出现了2个只出现一次的数字,将所有数字都异或之后的结果为这两个数字的异或。这个异或结果一定不为0,因此可以从中任意选择某一个不为0的位,将整个数组划分位这一位为0和为1两个分组。

比如两个只出现一次的数字分别为2和1,将整个数组异或之后的结果为11,选择1进行划分,则所有数组中的数字被分为1这一位上为0和1这一位上为1两个分组。

在每一个分组中,都满足除了一个数字出现了一次,其余数字都出现了两次,因此可以直接对所有数字进行异或得到结果。

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        total = nums[0]
        for i in range(1, len(nums)):
            total ^= nums[i]
            
        # 查找total不为0的任意1位
        diff = 1
        while total & diff == 0:
            diff <<= 1
            
        # 根据diff位是否为1将nums分为2个数组
        group = [[],[]]
        for num in nums:
            if diff & num == 0:
                group[0].append(num)
            else:
                group[1].append(num)
        
        results = []
        for g in group:
            result = g[0]
            for i in range(1, len(g)):
                result ^= g[i]
            results.append(result)
        return results

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值