作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


 

  • Difficulty: Easy

题目描述

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

Note:

  1. The given integer is guaranteed to fit within the range of a 32-bit signed integer.
  2. You could assume no leading zero bit in the integer’s 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.

解题方法

Java解法

找出一个二进制数的位反后的数。

本来想的是直接取反,也就是~num,但是试验下发现不行,因为有前面的0,取反后变成了1,然后就是个负数。

所以正确的方法应该是再与一下跟当前的数字的位数相同的全1的数字。其方法就是找出这个数字的第一个1,把后面的那些数字全部设为1.

没想到java竟然有这个库函数,那么就方便的多。

当然还有另外的方法,比如转成字符串,以此遍历到第一个1.

public class Solution {
    public int findComplement(int num) {
        return ~num & ((Integer.highestOneBit(num) << 1) - 1);
    }
}

AC: 12 ms

Python解法

二刷,python

用python做这种题比较性子直,直接按照题目说的嘛,把所有的0变成1,把所有的1变成0即可。那么直接转成二进制再用map函数求出补数,再变成10进制即可。

class Solution:
    def findComplement(self, num):
        """
        :type num: int
        :rtype: int
        """
        bin_num = bin(num)[2:]
        bin_ans = map(lambda x: '0' if x == '1' else '1', bin_num)
        return int(''.join(bin_ans), 2)

三刷,注意到求补数,就是把现有的二进制表示各位进行了0,1翻转,很容易想到异或操作。那么异或成1还是0呢?很简单的,我们需要把1变成0,以及0变成1,所以应该异或上每位都是1的二进制数。

如何获得二进制位数有多少呢?我是用的是len(bin(num)-2)的方式。如何构建全1的二进制数字?我是用的是用1移位,然后-1的方式。

代码如下。超过99%的提交。

class Solution:
    def findComplement(self, num):
        """
        :type num: int
        :rtype: int
        """
        return num ^ ((1 << (len(bin(num)) - 2)) - 1)

日期

2017 年 1 月 15 日
2018 年 7 月 4 日
2018 年 11 月 6 日 —— 腰酸背痛要废了