LeetCode 30 days Challenge - Day 23
本系列將對LeetCode新推出的30天算法挑戰進行總結記錄,旨在記錄學習成果、方便未來查閱,同時望爲廣大網友提供幫助。
Bitwise AND of Numbers Range
Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.
Example 1:
Input: [5,7]
Output: 4
Example 2:
Input: [0,1]
Output: 0
Solution
題目要求分析:給定一個整數m和一個整數n,m小於等於n,求將從n到m這些數的按位與的結果。
解法:
本題乍一看可以直接模擬,但是由於數字範圍很大,模擬的開銷太高,會TLE。
這裏介紹一種做法:
首先觀察:
0 0 0 0 0
1 0 0 0 1
2 0 0 1 0
3 0 0 1 1
4 0 1 0 0
5 0 1 0 1
6 0 1 1 0
7 0 1 1 1
8 1 0 0 0
這次0 - 8數字的二進制表示,可以看到,從右往左第 i 位
的規律是:從0開始,0重複 2i-1 次,1重複 2i-1 次,一直這樣循環下去。
再考慮與運算的特點:所有參加運算的數字中,出現了一個0,則結果就一定爲0,這是顯然的。
那麼,問題轉化爲:如何判斷m到n之間,每個比特位是否出現0?
- 從右往左,先確定當前
循環節長度的一半
:power = 1
(20),每向左一位,power *= 2
,注意不要爆INT。 - 確定循環節長度的一半後,對數字 k,
k / power
(2i)有以下情況:- 爲奇數:那麼k的二進制表示、從右往左第 i 位爲 1;
- 爲偶數:那麼k的二進制表示、從右往左第 i 位爲 0;
- 有了以上的結論後,結合題目給出的m、n考慮,對第 i 位,m / power以及n / power 有以下情況:
- 奇 + 奇,且爲同一個奇數:m到n,第 i 位,全是 1,該位置需要記入結果,
res += power
; - 奇 + 奇,但爲不同的奇數:m到n,第 i 位,兩個1中間存在0,該位置不需要記入結果;
- 奇 + 偶 / 偶 + 奇 /偶 + 偶:出現偶數,第 i 位存在 0,該位置不需要記入結果;
- 奇 + 奇,且爲同一個奇數:m到n,第 i 位,全是 1,該位置需要記入結果,
注:
- 注意while循環退出條件:當m小於power即可退出,因爲m小於power,那麼m表示爲二進制表示後,power對應的那一位爲0,不需要計入結果了。
- 注意power倍增不能爆INT,當power爲230次冪的時候,需要檢測判斷,並賦值爲INT_MAX,直接乘2會導致爆INT:INT_MAX = 231 - 1 < 231
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
if (m == n) return m;
int res = 0, power = 1;
while (power <= m) {
if ((m / power) % 2 != 0 && (m / power) == (n / power)) {
res += power;
}
if (power == INT_MAX/2 + 1) power = INT_MAX;
else power *= 2;
}
return res;
}
};
傳送門:Bitwise AND of Numbers Range
2020/4 Karl