力扣- -231. 2的幂
力扣- -231. 2的冪
文章目錄
- 力扣- -231. 2的冪
- 一、題目描述
- 二、問題分析
- 三、代碼
- 方法一:暴力統計
- 方法二:位運算(獲取二進制中最右邊的 1)
- 方法三:位運算(去除二進制中最右邊的 1)
看一道對位運算特別巧的簡單題
一、題目描述
class Solution { public:bool isPowerOfTwo(int n) {} };二、問題分析
- 這道題的主要思想是數字n的特殊性
- 因為數字n是2的冪(注意是2的冪,并不是2的倍數),那么這道題就簡單了,因為2的冪的數字的特性就是n的所有比特位中只有一個比特位為1;
三、代碼
方法一:暴力統計
class Solution { public:bool isPowerOfTwo(int n) {if(n == 0){return false;}while (n % 2 == 0) n /= 2;return n == 1;} };- 時間復雜度為 O(logN)O(logN)O(logN)
- 該問題將通過位運算在 O(1)O(1)O(1) 的時間復雜度解決,通過使用如下的按位技巧:
- 如何獲取二進制中最右邊的 1:xxx & (?x)(-x)(?x)。
- 如何將二進制中最右邊的 1 設置為 0:xxx & (x?1)(x - 1)(x?1)。
方法二:位運算(獲取二進制中最右邊的 1)
-
獲取最右邊的 1:xxx & (?x)(-x)(?x)。
-
首先討論為什么 xxx & (?x)(-x)(?x)可以獲取到二進制中最右邊的 1,且其它位設置為 0。
-
在補碼表示法中,?x-x?x === ?x?x?x +++ 111。換句話說,要計算 ?x?x?x,則要將 xxx 所有位取反再加 1。
-
在二進制表示中,?x?x?x +++ 111表示將該 1 移動到 ?x?x?x 中最右邊的 0 的位置上,并將所有較低位的位設置為 0。而 ?x?x?x 最右邊的 0 的位置對應于 xxx 最右邊的 1 的位置。
-
總而言之,?x-x?x === ?x?x?x +++ 111,此操作將 xxx 所有位取反,但是最右邊的 1 除外。
- 因此,xxx 和 ?x?x?x 只有一個共同點:最右邊的 1。這說明 xxx & (?x)(-x)(?x) 將保留最右邊的 1。并將其他的位設置為 0。
-
檢測是否為 2 的冪:
-
我們通過 xxx & (?x)(-x)(?x) 保留了最右邊的 1,并將其他位設置為 0 若 xxx 為 2 的冪,則它的二進制表示中只包含一個 1,則有 xxx & (?x)=x(-x) = x(?x)=x。
-
若 xxx 不是 2 的冪,則在二進制表示中存在其他 1,因此 xxx & (?x)!=x(-x) != x(?x)!=x。
-
因此判斷是否為 2 的冪的關鍵是:判斷 xxx & (?x)==x(-x) == x(?x)==x。
- 時間復雜度:O(1)O(1)O(1)。
- 空間復雜度:O(1)O(1)O(1)
方法三:位運算(去除二進制中最右邊的 1)
-
去除二進制中最右邊的 1:xxx & (x?1)(x - 1)(x?1)
-
首先討論為什么 xxx & (x?1)(x - 1)(x?1) 可以將最右邊的 1 設置為 0。
-
(x?1)(x - 1)(x?1) 代表了將 xxx 最右邊的 1 設置為 0,并且將較低位設置為 1。
-
再使用與運算:則 x 最右邊的 1 和就會被設置為 0,因為 1 & 0 = 0。
-
檢測是否為 2 的冪:
-
2 的冪二進制表示只含有一個 1。
-
xxx & (x?1)(x - 1)(x?1) 操作會將 2 的冪設置為 0,因此判斷是否為 2 的冪是:判斷 xxx & (x?1)==0(x - 1) == 0(x?1)==0。
- 時間復雜度:O(1)O(1)O(1)。
- 空間復雜度:O(1)O(1)O(1)
總之,這道題還是比較簡單的,就是位運算的運用
總結
以上是生活随笔為你收集整理的力扣- -231. 2的幂的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 缓存系统中的三座大山
- 下一篇: 什么是线段树?