【LeetCode題解】231_2的冪
阿新 • • 發佈:2018-12-19
描述
給定一個整數,編寫一個函式來判斷它是否是 2 的冪次方。
示例 1:
輸入: 1
輸出: true
解釋: 2^0 = 1
示例 2:
輸入: 16
輸出: true
解釋: 2^4 = 16
示例 3:
輸入: 218
輸出: false
解法 1:判斷整數 的二進位制表示中是否只有一位為1
實現方式 1:除以 2
讓我們先來看一下 2 的冪有什麼規律,
n | 2 的冪 | 二進位制表示 |
---|---|---|
0 | 0000 0001 |
|
1 | 0000 0010 |
|
2 | 0000 0100 |
|
3 | 0000 1000 |
|
… | … | … |
從上面可以看出,如果整數 是 2 的冪,將整數不斷除以 2,除了 1 之外,其餘的約數一定能被 2 整除。按照這樣的想法,我們就能寫出**解法 1 **的第一種實現。
Java 實現(非遞迴)
class Solution {
public boolean isPowerOfTwo(int x) {
if (x <= 0) {
return false;
}
while (x % 2 == 0) {
x /= 2;
}
return x == 1;
}
}
Python 實現(非遞迴)
class Solution:
def isPowerOfTwo(self, x):
"""
:type n: int
:rtype: bool
"""
if x <= 0:
return False
while x % 2 == 0:
x = x // 2
return x == 1
Java 實現(遞迴)
class Solution {
public boolean isPowerOfTwo(int x) {
return x > 0 && (x == 1 || (x % 2 == 0 && isPowerOfTwo(x / 2)));
}
}
Python 實現(遞迴)
class Solution:
def isPowerOfTwo(self, x):
"""
:type n: int
:rtype: bool
"""
return x > 0 and (x == 1 or (x % 2 == 0 and self.isPowerOfTwo(x // 2)))
複雜度分析
- **時間複雜度:**兩種實現(遞迴和非遞迴)的時間複雜度都是 的,其中 表示該整數
- **空間複雜度:**非遞迴實現的空間複雜度是 的,而遞迴實現的空間複雜度是 ,因此遞迴實現佔用系統棧的空間,遞迴的深度最多為
實現方式 2:位運算
對於實現方式 1,如果用二進位制的角度看,就是判斷整數的二進位制表示的最右邊一位是否為 1,如果為 1,則將該整數與 1 進行比較從而得到結果;如果不為 1,則將整數 右移一位(最高位補 0)。因此,我們就會想,是否有一種方式可以直接通過位運算就能達到目的,答案是肯定的。
讓我們再來看看下面的表格有什麼規律,
的二進位制表示 | 的二進位制表示 | |
---|---|---|
1 | 0000 0001 |
0000 0000 |
2 | 0000 0010 |
0000 0001 |
4 | 0000 0100 |
0000 0011 |
8 | 0000 1000 |
0000 0111 |
… | … | … |
從表格中可以看出,如果整數 是 2 的冪的話,整數 與 的二進位制表示進行與運算,結果為 0,因此我們就可以寫出解法 1 的第二種實現方式。
Java 實現
class Solution {
public boolean isPowerOfTwo(int x) {
return x > 0 && ((x & (x - 1)) == 0);
}
}
Python 實現
class Solution:
def isPowerOfTwo(self, x):
"""
:type n: int
:rtype: bool
"""
return x > 0 and (x & x - 1 == 0)
複雜度分析
- 時間複雜度:
- 空間複雜度: