劍指 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;
    }
}
相關文章
相關標籤/搜索