Leetcode May Challenge - 05/04: Number Complement(Python)

题目描述

Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation.

例子

Example 1:

Input: 5
Output: 2
Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2.
Example 2:

Input: 1
Output: 0
Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0.

解释

给一个十进制的数字,返回他二进制表示的补码表示的十进制数。比如5,二进制101,补码010,十进制2,返回2。

思路

思路1 暴力解

把十进制数字的二进制表示先用一个string存下来,然后对string取补码(遍历,是1就变0,反之变1)。再把新的string变成十进制数字。

思路2 异或

对于二进制,一位数字和1异或等于取反,和0异或等于取同。所以由这个思路我们想到,把给定数字的每一位直接和1异或不就好了吗?没错,这个思路就是这么简单。但具体怎么操作呢?我们不需要把十进制数字转化成二进制数字然后一位一位异或,那样代价太大。我们只需要再有一个数字,它的每一位都是0,只有我们需要异或的那一位是1。这样的数字大家肯定不陌生:1,2,4,8…只要是2的整数幂,都有这样的性质,我们这里把这个数字叫做mask。所以我们从1开始,每次把mask和给定数字异或,之后将mask乘2(实现时对于*=2的操作,可以用<<=1来表示,即二进制移位,喜欢哪一种写法都可以),直到我们把每一位异或完,就大功告成了!

代码

暴力解代码

class Solution(object):
    def findComplement(self, num):
        """
        :type num: int
        :rtype: int
        """
        if num == 0:
            return 1
        #得到数字的二进制表示
        str1 = ""
        while num > 0:
            print(num)
            str1 = str(num % 2) + str1
            num //= 2
        #对二进制取补码
        str2 = ""
        for s in str1:
            if s == '1':
                str2 += '0'
            else:
                str2 += '1'
        #用补码得到十进制
        ans = 0
        for i in range(len(str2)):
            ans += int(str2[len(str2) - i - 1]) * (2 ** i)
        return ans

异或代码

class Solution(object):
    def findComplement(self, num):
        """
        :type num: int
        :rtype: int
        """
        if num == 0:
            return 1
        #bit作为计数位,判断循环次数,即异或的位数
        bit = num
        #mask从1开始和num每一位异或
        mask = 1
        while bit:
            num ^= mask #异或符号
            bit >>= 1 #也可以写成bit //= 2
            mask <<= 1 #也可以写成mask *= 2
        return num
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值