トピックの背景
リートコードの質問461のハミング距離を実行しているときに、1の数を見つけるための非常に恥ずべきアルゴリズムを見つけました。これは素晴らしいことです!
実際、主題自体のアイデアは難しくありません、それは違いを尋ねるか、それから1の数を数えることですが、私はそれがこのように解決できるとは思っていませんでした。
BrianKneganアルゴリズムのアイデア
1の桁数を直感的に人間として数え、2つの1の間の0をスキップすることは可能ですか?例:10001000。
これは、ブライアン・カーニハンのビットカウントアルゴリズムの基本的な考え方です。アルゴリズムは、特定のビットと算術演算を使用して、1に等しい右端のビットを削除します。
numberとnumber-1に対してANDビット演算を実行すると、1に等しい元のnumbernumberの右端のビットが削除されます。
上記の考えに基づいて、1000分の1の数は2回の反復で知ることができます。
class Solution:
def hammingDistance(self, x, y):
xor = x ^ y
distance = 0
while xor:
distance += 1
# remove the rightmost bit of '1'
xor = xor & (xor - 1)
return distance
創意工夫
1を引いた後だから
- 右端の1は0になる必要があります
- 右端の1の右側にあるすべての0は1になる必要があります。
同時に:
- AND演算は、左側の数値には影響しません
- AND演算は、毎回右端の10を消去します
結果がすべて0でない限り(逆に、1がある限り)、上記のマイナス1およびAND演算を引き続き実行できます。各演算は1を表すため、1は巧妙に計算された数値です。
2進演算の特性に基づいて数値を見つけるのは本当に厄介です。これには、2進数を深く理解する必要があります。。天才。。