461. 漢明距離

啃不動的檸檬樹發表於2020-09-30

461. 漢明距離

描述

兩個整數之間的漢明距離指的是這兩個數字對應二進位制位不同的位置的數目。

給出兩個整數 x 和 y,計算它們之間的漢明距離。

注意:
0 ≤ x, y < 231.

示例:

輸入: x = 1, y = 4

輸出: 2

解釋:
1   (0 0 0 1)
4   (0 1 0 0)
       ↑   ↑

上面的箭頭指出了對應二進位制位不同的位置。

思路

(1)即求異或結果中1的個數。為了計算等於 1 的位數,可以將每個位移動到最右側,然後檢查該位是否為 1。

class Solution {
    public int hammingDistance(int x, int y) {
        int result = x ^ y;
        int m = 1;
        int count = 0;
        while(result != 0){
            //if(result % 2 == 1){  
            if((result & 1) == 1){
                count++;
            }
            result >>= 1;
        }
        return count;
    }
}

複雜度分析:

  • 時間複雜度:O(1),在 Python 和 Java 中 Integer 的大小是固定的,處理時間也是固定的。 32 位整數需要 32 次迭代。

  • 空間複雜度:O(1),使用恆定大小的空間。

(2)布賴恩·克尼根演算法(效率更高)

方法二是逐位移動,逐位比較邊緣位置是否為 1。尋找一種更快的方法找出等於 1 的位數。

是否可以像人類直觀的計數位元為 1 的位數,跳過兩個 1 之間的 0。例如:10001000。

上面例子中,遇到最右邊的 1 後,如果可以跳過中間的 0,直接跳到下一個 1,效率會高很多。

這是布賴恩·克尼根位計數演算法的基本思想。該演算法使用特定位元位和算術運算移除等於 1 的最右位元位。

當我們在 number 和 number-1 上做 AND 位運算時,原數字 number 的最右邊等於 1 的位元會被移除。

在這裡插入圖片描述
基於以上思路,通過 2 次迭代就可以知道 10001000 中 1 的位數,而不需要 8 次。即只需對最後一位1做運算,而不需對每一位都要與1相與來統計個數,效率更高。

class Solution {
  public int hammingDistance(int x, int y) {
    int xor = x ^ y;
    int distance = 0;
    while (xor != 0) {
      distance += 1;
      // remove the rightmost bit of '1'
      xor = xor & (xor - 1);
    }
    return distance;
  }
}

複雜度分析:

  • 時間複雜度:O(1)。

    • 與移位方法相似,由於整數的位數恆定,因此具有恆定的時間複雜度。

    • 但是該方法需要的迭代操作更少。

  • 空間複雜度:O(1),與輸入無關,使用恆定大小的空間。

相關文章