【经典题目】只出现x次的数字——异或操作

只出现x次的数字–巧用异或

入门级:只出现一次,其余数字出现了偶数次

【经典题目】只出现x次的数字——异或操作_第1张图片
很简单了,直接利用异或的性质,每次将数组所有数字的异或在一起,因为其他数字都出现了偶数次,所以异或结果就是唯一的奇数次的。

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

升级版:两个元素出现1次,其余出现两次

【经典题目】只出现x次的数字——异或操作_第2张图片
如果数组中有两个数字,问题就变的复杂了起来。因为难以区分两个数字。但是如果我们还是利用异或的性质的话还是可以发现一些端倪的。我们将整个数组异或起来,最后的结果肯定是两个数单独数字的异或和。因此我们可以分析这个二进制的数字,如果某一位是1说明两个数字在该位分别是0和1。因此我们可以利用这个特点对两个数字进行区分。

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        cur = 0
        for i in nums:
            cur ^= i
        h = cur&(-cur)  # 找出cur的最后一个1, h=00000010000
        a = 0
        b = 0
        for i in nums:
            if h&i == 0:
                a ^= i
            else:
                b ^= i
        return [a, b]

最终版:其余元素出现了三次

【经典题目】只出现x次的数字——异或操作_第3张图片

这个就比较麻烦了,需要借助状态转移的方法,因为我们要转换为3进制。保证每次计数时候,从00-->01-->10-->00因此我们借助one和two两个。进行考虑。
参考题解

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        one = 0
        two = 0
        for i in nums:
            one,two = (one^i)&(~two), ((~one)&(two&~i))|(one&i)
        return one

你可能感兴趣的:(leetcode经典题目)