剑指 offer——位操作篇

Posted yzihan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 offer——位操作篇相关的知识,希望对你有一定的参考价值。

15. 二进制中1的个数

题意:面试题15. 二进制中1的个数
思路:使用位操作,每次计算给定数字的某一个二进制位上是否为1。由于1的二进制表示中,只有末位为1,其余位均为0,所以将给定的数与1进行按位与操作,即可判断其末位上的二进制位是否为1。

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int count = 0;
        while (n != 0) {
            if ((n & 1) == 1) {
                count ++;
            }
            n = n >>> 1;
        }
        return count;
    }
}

16. 数值的整数次方

题意:面试题16. 数值的整数次方
思路:将n个x相乘,计算 (x^n) 需要的时间复杂度为O(n),当n特别大时,不满足时间要求。
由于 (x^{a+b} = x^a*x^b),按照这种方式将n写成二进制的形式,并进行拆分,那么只计算二进制位上为1时的乘积,这种算法需要O(log(n))的时间复杂度。如x=2,n=6时:

[2^6 = 2^{110}(将6转换成2进制) = 2^{100} * 2^{10} = 2^4 * 2^2 ]

class Solution {
    public double myPow(double x, int n) {
        if (n == 0) {
            return 1;
        }
        boolean negative = n < 0;
        long newN = Math.abs((long)n);
        double res = 1;
        double tmp = x;
        while (newN != 0) {
            if ((newN & 1) == 1) {
                res *= tmp;
            }
            tmp *= tmp;
            newN >>= 1;
        }
        return negative ? 1 / res : res;
    }
}

65. 不用加减乘除做加法

题意:面试题65. 不用加减乘除做加法
思路:异或运算。

class Solution {
    public int add(int a, int b) {
        int carry;
        while (b != 0) {
            carry = (a & b) << 1;
            a = (a ^ b);
            b = carry;
        }
        return a;
    }
}




以上是关于剑指 offer——位操作篇的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer--3

剑指offer-11-二进制中1的个数

剑指offer—左旋转字符串

剑指Offer 位运算小合集

剑指offer思路总结

剑指Offer之二进制中1的个数