blog

LeetCode201.ビットによる数値の範囲。

データが大きいとタイムアウトします。 ビットですべての数を行うには、0ビットの数がある限り、ビットの結果を持つ最後のビットは0でなければならないことに注意してください。 ビット和の結果は、すべて...

Mar 18, 2020 · 2 min. read
Share this

問題では最大データが2147483647とあるので、ビット0から30までを列挙し、すべての数値の各ビットに対してand演算を行えばよいのです。

データが大きいとタイムアウトします。

すべての数の位取り和を求めるには、桁の1つが0である限り、最終的な位取り和の結果もその場所で0でなければならないことに注意してください。

例えば、9、10、11、12を合計した場合、下位3桁はそれぞれその桁の数字が0なので、最終的な和の結果は下位3桁は0になり、4桁すべてが1である末尾4桁だけは和の結果が1になるので、その桁で合計したすべての数字の最終的な結果は末尾4桁で1になります。 上位桁の数字はすべて0なので、それ以上のことはありません。

ビット和の結果は、すべての数値の2進数の共通接頭辞であり、下位ビットはすべて0であることがわかります。たとえば、上記の例では、共通接頭辞は最後から4ビット目の1であり、下位3ビットはすべて0であるため、結果は1 0 0 0 0となり、8となります。

mからnまでの各数が少しずつ1ずつ加算されていくので、1ずつ加算されるたびに低い位置から変わっていくことになります。したがって、すべての数の共通接頭辞は、左右の端点mとnの共通接頭辞となります。したがって、mとnの共通接頭辞を求め、低い位置をすべて0で埋めればよいことになります。

共通接頭辞を求めるには、右シフト演算を使います。mとnを、2つの数が等しくなるまで同時に右にシフトします。もちろん、シフトした回数を記録しておき、シフトした回数だけmを左にシフトするのが最終的な答えです。

例えば上の図では、9と12は右に3回シフトした後、つまり共通の接頭辞1を見つけた後、1を左に3回シフトした後、等しくなります。

コードは以下の通り:

class Solution {
public:
 int rangeBitwiseAnd(int m, int n) {
 int shift = 0; //右シフトの回数を記録する
 while(m < n) { //mとnを同時に2つの数が等しくなるまで右シフトする。
 m >>= 1;
 n >>= 1;
 ++shift;
 }
 return m << shift; //whileループを抜けた後、mとnが共通の接頭辞となり、左に3回シフトした結果が答えとなる。
 }
};
Read next

スプリング_クラウド_ナコス

1. エンドポイント設定手順 2. nacosクラスタのインストール 3. yumによるjdk8のインストール 4. ファイアウォール関連コマンド

Mar 18, 2020 · 2 min read