476. Number Complement

题目描述和难度

  • 题目描述:

给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。

注意:

  1. 给定的整数保证在32位带符号整数的范围内。
  2. 你可以假定二进制数不包含前导零位。

示例 1:

输入: 5
输出: 2
解释: 5的二进制表示为101(没有前导零位),其补数为010。所以你需要输出2。

示例 2:

输入: 1
输出: 0
解释: 1的二进制表示为1(没有前导零位),其补数为0。所以你需要输出0。

思路分析

求解关键:

1、使用二进制的字符串表示进行字符串的拼接; 2、使用 mask 小技巧以及异或运算完成 1 变 0 , 0 变 1;

参考解答

参考解答1:容易想到

public class Solution {

    /**
     * 使用 Java 库函数 Integer.toBinaryString() 将一个整数转换为二进制字符串表示
     * @param num
     * @return
     */
    public int findComplement(int num) {
        if (num <= 0) {
            throw new IllegalArgumentException("输入的数字不是正整数");
        }
        String numStr = Integer.toBinaryString(num);
        StringBuilder stringBuilder = new StringBuilder();
        for (Character c : numStr.toCharArray()) {
            if (c == '0') {
                stringBuilder.append(1);
            } else {
                stringBuilder.append(0);
            }
        }
        numStr = stringBuilder.toString();
        return Integer.valueOf(numStr, 2);
    }
}

参考解答2:典型

public class Solution2 {

    public int findComplement(int num) {
        if (num <= 0) {
            throw new IllegalArgumentException("输入的数字不是正整数");
        }
        // 这个复制出来的数对运算结果不起直接作用,只是用来判断需要取反的操作的次数
        int numCopy = num;
        int mask = 1;
        // 正整数,右移,左边补 0
        while (numCopy > 0) {
            // 和 1 做异或操作:0 1 -> 1 ,1 1 -> 0:
            // 和 0 做异或操作:1 0 -> 1 ,0 0 -> 0:
            num ^= mask;
            mask <<= 1;
            numCopy >>= 1;
        }
        return num;
    }
}

本篇文章的地址为 https://liweiwei1419.github.io/leetcode-solution/leetcode-0476-number-complement ,如果我的题解有错误,或者您有更好的解法,欢迎您告诉我 liweiwei1419@gmail.com