1. 題目
題目地址(231. 2 的冪 - 力扣(LeetCode))
https://leetcode.cn/problems/power-of-two/?envType=study-plan-v2&envId=primers-list
題目描述
給你一個整數 n
,請你判斷該整數是否是 2 的冪次方。如果是,返回 true
;否則,返回 false
。
如果存在一個整數 x
使得 n == 2x
,則認為 n
是 2 的冪次方。
示例 1:
輸入:n = 1 輸出:true 解釋:20 = 1
示例 2:
輸入:n = 16 輸出:true 解釋:24 = 16
示例 3:
輸入:n = 3 輸出:false
提示:
-231 <= n <= 231 - 1
進階:你能夠不使用迴圈/遞迴解決此問題嗎?
2.題解
由於迴圈/遞迴較為簡單, 這裡就省略這兩種寫法了
2.1 位運算
思路
一個\(2^x\), 他的二進位制表示必然只有一個1, 可以想象一下, 每次 *2 其實就是將這個 1 向前推進一個, 但是並沒有多出 1
所以我們的目標就是確定這個二進位制是否只有一個1即可
需要注意的是位運算 & 的運算優先順序低於 &&, 所以一定要打好括號!!!!!
這裡有兩種方法:
1.n & (n - 1)
去除最低位1
可以直接去除最低位的1, 然後我們判斷是否剩餘是0即可!
程式碼
class Solution {
public:
bool isPowerOfTwo(int n) {
return (n > 0) && (n & (n-1)) == 0;
}
};
2.n & (-n)
獲取最低位1
由於負數是按照補碼規則在計算機中儲存的,−n 的二進位制表示為 n 的二進位制表示的每一位取反再加上 1
由於取反, 其餘高位部分做&運算均為0; 而低位部分取反加1又恢復了只有那個最低位1的情況, 所以 n & (-n) 最後只會得到低位1
這樣我們只要判斷是不是 n & (-n) = n 即可, 說明只有這個最低位1
程式碼
class Solution {
public:
bool isPowerOfTwo(int n) {
return (n > 0) && (n & (-n)) == n;
}
};
2.2 逆向思維
思路
我們無論是遞迴還是迴圈,都是希望將該數作為被除數, 不斷除2判斷出結果
但是我們發現這裡最大可能的是\(2^30\), 如果該數是\(2^30\)的約數, 因為\(2^30\)是純由2組成的積, 所以我們就可以直接斷定該數肯定也是純由2組成的積, 找不到其他質數因子了!
程式碼
class Solution {
public:
bool isPowerOfTwo(int n) {
return (n > 0) && ((int)pow(2, 30) % n) == 0;
}
};