LeetCode 260. Single Number III解题报告(python)

本文介绍了解决LeetCode上260题“Single Number III”的两种方法。一种是通过集合记录单次和双次出现的元素,另一种是利用异或操作找出仅出现一次的两个元素。详细解析了异或操作原理及如何通过此方法区分两个唯一元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

260. Single Number III

  1. Lowest Common Ancestor of Deepest Leaves python solution

题目描述

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.
在这里插入图片描述

解析

给出两种方法进行求解。第一种是简单粗暴的,见代码

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        one = set()
        double = set()
        for n in nums:
            if n not in one:
                one.add(n)
            else:
                double.add(n)
                
        return list(one - double)

第二种是使用异或操作的,需要讲解一下基础知识。

A xor A=0
0 xor A=A
并且 xor 满足交换律和结合律。
比如 2 2 3 1 3,2 xor 2 xor 3 xor 1 xor 3
= 2 xor 2 xor 3 xor 3 xor 1
=(2 xor 2) xor (3 xor 3) xor 1
= 0 xor 0 xor 1
= 1

如果将所有的数字都xor 一遍,那结果是什么呢。假设只出现一次的两个数是 A、B,那我们最后只能得到一个值 = A xor B,但没有办法知道 A 是多少,B 是多少。
xor 是按位比较,相同为0,不同为1,也就是说得到的这个值里,所有的1都代表了:在这个位置上,A 和 B 是不同的,这给我们区分 A B 提供了一个方法:
我们随便找一个是1的位置(也就是 A和B 在这个位置上的值反正有一个是0 有一个是1),再次遍历一遍数组,按照这个位置上是0还是1分成两组,那么 A 和 B 一定会被分开。而对于其他的数字,无论他们在这个位置上是0还是1,总之他们会两两一对分到两个组中的任意一个组里去。
这就转化成了初级版本的问题了,每个组中都只有一个数出现1次,对两个组分别做一次xor ,得到两个数就是 A 和 B。

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        xor = 0
        a = 0
        b = 0
        for num in nums:
            xor ^= num
        mask = 1
        while(xor&mask == 0):
            mask = mask << 1
        for num in nums:
            if num&mask:
                a ^= num
            else:
                b ^= num
        return [a, b]

Reference

https://leetcode.com/problems/single-number-iii/discuss/68907/Naive-Python
https://leetcode.com/problems/single-number-iii/discuss/68931/Easy-Python-O(n)-O(1)-solution

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值