位运算的神奇之处(python)

题目
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)

输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]

先上代码

from functools import reduce
class Solution:
    def singleNumbers(self, nums: List[int]) -> List[int]:
    	def lowbit(x):
    		return x&(-x)
        tmp=reduce(lambda x,y:x^y,nums)
        mask=lowbit(tmp)
        res=[0,0]
        for element in nums:
            if element&mask==0:
                res[0]=res[0]^element
            else:
                res[1]=res[1]^element
        
        return res

由于两个相同的数异或^得到0,不同的数异或得到1(同0异1)
那么我们对所有的数组元素进行^操作
结果实际上等于对那两个不同的数进行^操作
假设那两个不同的数 二进制表示为
xxx100
xxx000
而进行异或操作后:xxx100 ^ xxx000 = ???100
我们用lowbit函数得到数字二进制最右边为1的数字
比如 6,写成二进制 110,那么lowbit(6)=2
再比如7,写成二进制111,那么lowbit(7)=1

def lowbit(x):
	return x&(-x)

而对于xxx100,xxx000异或后得到???100
lowbit可以理解成巧妙地去掉了前面的???
lowbit(???100)=100,我们称这个数是mask
那么对于这两个不同的数字,它们和mask做&运算,一定一者为0,另一者为非0!!这不就恰恰分离开来了吗?
xxx100 & 100 = 000100(非0)
xxx000 & 100 = 000000(为0)
最后利用了两个相同的数^操作为0
输出res即可

猜你喜欢

转载自blog.csdn.net/weixin_39666736/article/details/104288100
今日推荐