天天看點

關于 i & (1<<j) 和 1 & (i>>j) 的解釋

  <code>1&lt;&lt;j</code>表示二進制表示的<code>1</code>(即<code>0001</code>)的所有位向左平移<code>j</code>個機關後的數,如<code>j=1</code>,則平移後的結果是<code>0010</code>,此時得到數<code>2</code>。若<code>j=3</code>,平移後的結果是<code>1000</code>,此時得到數<code>8</code>。向左平移<code>j</code>位,即表示将原來的數乘上<code>2^j</code>。可以類比十進制,所有位左移<code>j</code>位,相當于在後面添了<code>j</code>個<code>0</code>,即乘上<code>10^j</code>,在二進制中,即乘上<code>2^j</code>。

  <code>&amp;</code>在此處表示按位與,即兩個二進制表示的數,在對應位置上進行取并的操作,都為<code>1</code>時取<code>1</code>,否則取<code>0</code>。如<code>1010</code>(十進制的10)和<code>0101</code>(十進制的5)進行按位與操作後,得到的是<code>0000</code>(十進制的0)。

  <code>i &amp; (1&lt;&lt;j)</code>則表示 <code>i</code> 和 <code>1&lt;&lt;j</code>(即<code>2^j</code>) 按位與後得到的數。<code>1&lt;&lt;j</code>的二進制表示隻有第<code>j</code>個位置(從右往左數,從0開始)上的數是<code>1</code>,其餘位置上的數是<code>0</code>,<code>i</code>和<code>1&lt;&lt;j</code> 進行按位與操作時,<code>i</code>的第<code>j</code>個位置是<code>1</code>就傳回<code>1&lt;&lt;j</code>(判斷語句中即為<code>true</code>),<code>i</code>的第<code>j</code>個位置是<code>0</code>就傳回<code>0</code>(判斷語句中即為<code>false</code>)。

具體地,

當<code>i=0</code>時,任何<code>j</code>都不滿足。

當<code>i=1</code>時,<code>j=0</code> 滿足條件。

當<code>i=2</code>時,<code>j=1</code> 滿足條件。

當<code>i=3</code>時,<code>j=0,1</code> 滿足條件。

當<code>i=4</code>時,<code>j=2</code> 滿足條件。

當<code>i=5</code>時,<code>j=0,2</code> 滿足條件。

當<code>i=6</code>時,<code>j=1,2</code> 滿足條件。

當<code>i=7</code>時,<code>j=0,1,2</code> 滿足條件。

當<code>i=8</code>時,<code>j=3</code> 滿足條件。

...

當<code>i=2^n-1</code>時,<code>j=0,1,2,...,n-1</code> 滿足條件。

  歸納一下,如果<code>j</code>表示數組<code>a</code>(長度為<code>n</code>)的索引,循環結構如下,則表示依次選取數組<code>a</code>的一個子數組進行操作,直到選到它本身。

  例子:LeetCode 2044. 統計按位或能得到最大值的子集數目(中等),代碼參考文獻1

例如,當<code>a=[3,1]</code>時,

<code>i=1,j=0</code>時,取<code>[3]</code>,<code>tem=3,res=3,cnt=1</code>;

<code>i=2,j=1</code>時,取<code>[1]</code>,<code>tem=1,res=3,cnt=1</code>;

<code>i=3,j=0</code>時,取<code>[3]</code>,<code>tem=3</code>;

<code>i=3,j=1</code>時,取<code>[1]</code>,<code>tem=3,res=3,cnt=2</code>。

傳回2。

  <code>1 &amp; (i&gt;&gt;j)</code>相當于<code>i</code> 右移 <code>j</code> 位後,若為奇數則傳回<code>1</code>,若為偶數則傳回<code>0</code>。代碼相當于:

若<code>i&gt;=0 &amp;&amp; i &lt; 2^n ,j&gt;=0 &amp;&amp; j&lt;n</code>,具體地,

當<code>i=1</code> 時,<code>j=0</code>滿足條件。

當<code>i=2</code> 時,<code>j=1</code>時滿足條件。

當<code>i=3</code> 時,<code>j=0,1</code>時滿足條件。

當<code>i=4</code> 時,<code>j=2</code>時滿足條件。

當<code>i=5</code> 時,<code>j=0,2</code>時滿足條件。

當<code>i=6</code> 時,<code>j=1,2</code>時滿足條件。

當<code>i=7</code> 時,<code>j=0,1,2</code>時滿足條件。

當<code>i=8</code> 時,<code>j=3</code>時滿足條件。

當<code>i=2^n-1</code> 時,<code>j=0,1,2,...,n-1</code>時滿足條件。

  歸納,<code>1 &amp; (i&gt;&gt;j)</code> 和<code>i &amp; (1&lt;&lt;j)</code>的效果一樣,都是依次取出<code>[0,1,2,...,n-1]</code>的子集,直到取到其本身。

1.5904. js 暴力