231. 2 的冪
一個數 \(n\) 是 \(2\) 的冪,當且僅當 \(n\) 是正整數,並且 \(n\) 的二進位制表示中僅包含 1 個 1。
因此我們可以考慮使用位運算,將 \(n\) 的二進位制表示中最低位的那個 \(1\) 提取出來,再判斷剩餘的數值是否為 \(0\) 即可。下面介紹兩種常見的與「二進位制表示中最低位」相關的位運算技巧。
第一個技巧是
\[\texttt{n & (n - 1)} \]其中 \(\texttt{&}\) 表示按位與運算。該位運算技巧可以直接將 \(n\) 二進位制表示的最低位 \(1\) 移除,它的原理如下:
假設 \(n\) 的二進位制表示為 \((a 10\cdots 0)_2\)
我們將 \((a 10\cdots 0)_2\)與 \((a 01\cdots1)_2\) 進行按位與運算,高位 \(a\) 不變,在這之後的所有位都會變為 0,這樣我們就將最低位的那個 1 移除了。
因此,如果 \(n\) 是正整數並且 \(\texttt{n & (n - 1) = 0}\),那麼 \(n\) 就是 2 的冪。
第二個技巧是\(\texttt{n & (-n)}\) 其中 \(-n\)
由於負數是按照補碼規則在計算機中儲存的,\(-n\) 的二進位制表示為 \(n\) 的二進位制表示的每一位取反再加上 1,因此它的原理如下:
假設 \(n\) 的二進位制表示為 \((a 10\cdots 0)_2\) ,其中 \(a\) 表示若干個高位,1 表示最低位的那個 1,\(0\cdots 0\) 表示後面的若干個 0,那麼 \(-n\) 的二進位制表示為:
\[(\bar{a} 01\cdots1)_2 + (1)_2 = (\bar{a} 10\cdots0)_2 \]其中 \(\bar{a}\)
因此,如果 \(n\) 是正整數並且 \(\texttt{n & (-n) = n}\),那麼 \(n\) 就是 2 的冪。
注意點
在一些語言中,位運算的優先順序較低,需要注意運算順序。
class Solution {
public:
bool isPowerOfTwo(int n) {
return n > 0 && (n & (n - 1)) == 0;
}
};
class Solution {
public:
bool isPowerOfTwo(int n) {
return n > 0 && (n & -n) == n;
}
};