Leetcode题解-算法-位运算(Python版)

1 统计两个数二进制位多少位不同

461. 汉明距离(Easy)

方法一:移位实现位计数
两数异或,不同的位会保留下来

class Solution:
    def hammingDistance(self, x: int, y: int) -> int:
        x = x^y
        count = 0
        while x > 0:
            if x%2:
                count += 1
            x = x >> 1
        return count

方法二:

class Solution:
    def hammingDistance(self, x: int, y: int) -> int:
        x = x^y
        count = 0
        while x > 0:
            count += 1
            x &= x - 1
        return count

2 数组中唯一一个不重复的数

136. 只出现一次的数字(Easy)

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

3 寻找数组中缺失的数

268. 丢失的数字(Easy)
方法一:数学

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        n = len(nums)
        return n*(n+1)//2 - sum(nums)

时间复杂度:O(n)
空间复杂度:O(1)

方法二:位运算
将数组中的所有数和原本不缺失的所有数异或,除了缺失的数,其他都出现两次,所以结果为缺失的数。
例:Value 0 1 3 4
missing
=0∧(1∧0)∧(2∧1)∧(3∧3)∧(4∧4)
=(0∧0)∧(1∧1)∧(3∧3)∧(4∧4)∧2
=0∧0∧0∧0∧2
=2

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        res = 0
        for i, num in enumerate(nums):
            res = res ^ (i+1) ^ num
        return res

时间复杂度:O(n)
空间复杂度:O(1)

4 不重复的两个数字

260. 只出现一次的数字 III(Medium)

方法一:用hash表统计每个元素出现的次数

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        nums_map = Counter(nums)
        res = [k for k, v in nums_map.items() if v ==1]
        return res

时间复杂度:O(n)
空间复杂度:O(n)

方法二:位运算

将所有元素异或,得到这两个不重复元素的异或值,找出从低位向高位第一个不相等的位(异或值该位等于1)
按照该位等于0和等于1,将元素分为两个组,分别异或就可以找出两个不相等的元素了。

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        xor = 0
        for num in nums:
            xor ^= num
        xor = xor & (-xor)

        res1, res2 = 0, 0
        for num in nums:
            if xor & num:
                res1 ^= num
            else:
                res2 ^= num
        return [res1, res2]

5 判断一个数是不是 2 的 n 次方

231. 2 的幂(Easy)

方法一:
如果是 2 的 n 次方,则二级制数中只有一个 2。

class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        return n > 0 and n&(n-1) == 0

时间复杂度:O(1)
空间复杂度:O(1)

方法二:判断是否为最大 22 的幂的约数
在题目给定的 32 位有符号整数的范围内,最大的 2 的幂为 230,只要判断 n 是否是 230 的约数即可。

class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        BIG = 1 << 30
        return n > 0 and BIG % n == 0

时间复杂度:O(1)
空间复杂度:O(1)

6 判断一个数是不是 4 的 n 次方

342. 4的幂(Easy)

要使得数是 4 的 n 次方,该数的二进制数中只有一个 1,且在奇数位置上。

class Solution:
    def isPowerOfFour(self, n: int) -> bool:
        return n > 0 and n & (n - 1) == 0 and n & 0xaaaaaaaa == 0

时间复杂度:O(1)
空间复杂度:O(1)

方法二:取模性质

如果 n 是 4 的幂,那么可以表示成 4x 的形式,它除以 3 的余数一定为 1,即:
4x=(3+1)x
=> (4x) mod 3 = ((3+1)x) mod 3 = 1

如果 n 是 2 的幂却不是 4 的幂,那么它可以表示成 4x ×2 的形式,此时它除以 3 的余数一定为 2。因此我们可以通过 n 除以 3 的余数是否为 1 来判断 n 是否是 4 的幂。

class Solution:
    def isPowerOfFour(self, n: int) -> bool:
        return n > 0 and n & (n - 1) == 0 and n % 3 == 1

时间复杂度:O(1)
空间复杂度:O(1)

7 查看整数二进制位 0 和 1 是否交替出现

693. 交替位二进制数(Easy)

方法一:位运算
如果 n 的二进制位为 0,1 交错,将 n 右移一位与自身相“异或”,则结果全为 1。结果加 1 之后和自身“与”为 0。

class Solution:
    def hasAlternatingBits(self, n: int) -> bool:
        a = n ^ (n>>1)
        return a & a+1 == 0

时间复杂度:O(1)
空间复杂度:O(1)

方法二:模拟

class Solution:
    def hasAlternatingBits(self, n: int) -> bool:
        pre = n%2
        while n > 0:
            n = n >> 1
            cur = n % 2
            if pre == cur:
                return False
            pre = cur
        return True

时间复杂度:O(logn)
空间复杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值