1. 程式人生 > >【LeetCode題解】231_2的冪

【LeetCode題解】231_2的冪

描述

給定一個整數,編寫一個函式來判斷它是否是 2 的冪次方。

示例 1:

輸入: 1
輸出: true
解釋: 2^0 = 1

示例 2:

輸入: 16
輸出: true
解釋: 2^4 = 16

示例 3:

輸入: 218
輸出: false

解法 1:判斷整數 xx 的二進位制表示中是否只有一位為1

實現方式 1:除以 2

讓我們先來看一下 2 的冪有什麼規律,

n 2 的冪 二進位制表示
0 20=12^0 = 1 0000 0001
1 21=22^1 = 2 0000 0010
2 22=42^2 = 4 0000 0100
3 23=82^3 = 8 0000 1000

從上面可以看出,如果整數 xx 是 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)))

複雜度分析

  • **時間複雜度:**兩種實現(遞迴和非遞迴)的時間複雜度都是 O(log(x))O(\log(x)) 的,其中 xx 表示該整數
  • **空間複雜度:**非遞迴實現的空間複雜度是 O(1)O(1) 的,而遞迴實現的空間複雜度是 O(log(x))O(\log(x)),因此遞迴實現佔用系統棧的空間,遞迴的深度最多為 log(x)\log(x)

實現方式 2:位運算

對於實現方式 1,如果用二進位制的角度看,就是判斷整數的二進位制表示的最右邊一位是否為 1,如果為 1,則將該整數與 1 進行比較從而得到結果;如果不為 1,則將整數 xx 右移一位(最高位補 0)。因此,我們就會想,是否有一種方式可以直接通過位運算就能達到目的,答案是肯定的。

讓我們再來看看下面的表格有什麼規律,

2n2^n 2n2^n 的二進位制表示 2n12^n - 1 的二進位制表示
1 0000 0001 0000 0000
2 0000 0010 0000 0001
4 0000 0100 0000 0011
8 0000 1000 0000 0111

從表格中可以看出,如果整數 xx 是 2 的冪的話,整數 xxx1x - 1 的二進位制表示進行與運算,結果為 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)

複雜度分析

  • 時間複雜度:O(1)O(1)
  • 空間複雜度:O(1)O(1)