剑指 offer——位操做篇

15. 二进制中1的个数

题意:面试题15. 二进制中1的个数
思路:使用位操做,每次计算给定数字的某一个二进制位上是否为1。因为1的二进制表示中,只有末位为1,其他位均为0,因此将给定的数与1进行按位与操做,便可判断其末位上的二进制位是否为1。java

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;
    }
}
相关文章
相关标签/搜索