Leetcode 260. Single Number Ⅲ

Leetcode 260. Single Number Ⅲ_第1张图片

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

这个问题的解法只需要将数组中所有的数字都进行异或,最后的结果就是只出现了一次的数字。原因是任何两个相同的数字异或结果都为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

 

你可能感兴趣的:(算法)