The Hamming distance between two integers is the number of positions at which the corresponding bits are different.
Given two integers x
and y
, calculate the Hamming distance.
Note:
0 ≤ x
, y
< 231.
Example:
Input: x = 1, y = 4 Output: 2 Explanation: 1 (0 0 0 1) 4 (0 1 0 0) ↑ ↑ The above arrows point to positions where the corresponding bits are different.
這道題讓我求兩個數字之間的漢明距離,題目中解釋的很清楚了,兩個數字之間的漢明距離就是其二進制數對應位不同的個數,那么最直接了當的做法就是按位分別取出兩個數對應位上的數並異或,我們知道異或的性質上相同的為0,不同的為1,我們只要把為1的情況累加起來就是漢明距離了,參見代碼如下:
解法一:
class Solution { public: int hammingDistance(int x, int y) { int res = 0; for (int i = 0; i < 32; ++i) { if ((x & (1 << i)) ^ (y & (1 << i))) { ++res; } } return res; } };
我們可以對上面的代碼進行優化,我們可以一開始直接將兩個數字異或起來,然后我們遍歷異或結果的每一位,統計為1的個數,也能達到同樣的效果,參見代碼如下:
解法二:
class Solution { public: int hammingDistance(int x, int y) { int res = 0, exc = x ^ y; for (int i = 0; i < 32; ++i) { res += (exc >> i) & 1; } return res; } };
經過副博主@fantasywindy的提醒,上面的遍歷每一位的方法並不高效,還可以進一步優化,假如數為num, num & (num - 1)可以快速地移除最右邊的bit 1, 一直循環到num為0, 總的循環數就是num中bit 1的個數。參見代碼如下:
解法三:
class Solution { public: int hammingDistance(int x, int y) { int res = 0, exc = x ^ y; while (exc) { ++res; exc &= (exc - 1); } return res; } };
我們再來看一種遞歸的寫法,非常的簡潔,遞歸終止的條件是當兩個數異或為0時,表明此時兩個數完全相同,我們返回0,否則我們返回異或和對2取余加上對x/2和y/2調用遞歸的結果。異或和對2取余相當於檢查最低位是否相同,而對x/2和y/2調用遞歸相當於將x和y分別向右移動一位,這樣每一位都可以比較到,也能得到正確結果,參見代碼如下:
解法四:
class Solution { public: int hammingDistance(int x, int y) { if ((x ^ y) == 0) return 0; return (x ^ y) % 2 + hammingDistance(x / 2, y / 2); } };
參考資料:
https://discuss.leetcode.com/topic/72089/java-3-line-solution
https://discuss.leetcode.com/topic/72093/java-1-line-solution-d
https://discuss.leetcode.com/topic/72289/0ms-c-two-line-solution