Leetcode 600 Non-negative Integers without Consecutive Ones
阿新 • • 發佈:2019-02-12
Given a positive integer n, find the number of non-negative integers less than or equal to n, whose binary representations do NOT contain consecutive ones.
Example 1:
Input: 5
Output: 5
Explanation:
Here are the non-negative integers <= 5 with their corresponding binary representations:
0 : 0
1 : 1
2 : 10
3 : 11
4 : 100
5 : 101
Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule.
Note: 1 <= n <=
在小於等於n的數中,找到所有滿足相鄰的bit位不同時為1的數.
這個可以對數字的最高位進行討論:假設n的最高位在K
1. 找最高位也是K的無”11”數
2. 找最高位小於K的無”11”數
兩部分加起來就是我們要的結果.
就最高位小於K的時候, 這個就比較好算了. 因為這些數一定是小於n的.
記最高位1 為 i 的無”11”數有 a[i] 種,
101xxx
1001xx
10001x
100001
100000
a[i] = a[i-2]+a[i-3] + … + a[0]
可進一步推得a[i] = a[i-1]+a[i-2].
對於最高位為K的數就比較麻煩了, 因為有小於等於n的限制在這.
遍歷n的bit位, 從高到低. 如果遇到一個bit為1, 我們就把這位設為0, 剩下低位的部分就可以用上面a[i]來填補了.
1001001
1000xxx
剩下的這3個bits用a[3], a[2], a[1],a[0]對應的那些數來填補就可以了.
a還有一種特殊情況: n中包含”11”. 這樣n這個數就不能算進去了. 而且在遇到最高的”11”的時候, 我們需要把它變為”10”, 或”01”.
1011010101
100xxxxxxx 剩下的7位用a[7],a[6], ..a[0]對應的數填補
1010xxxxxx 剩下的6位用a[6],a[5], ... a[0]對應的數來填補
為了計算方便, 我們可以先計算sum[i] = a[i] + a[i-1] + … + a[0]
class Solution {
public:
/**
* @brief 找到二進位制中最高位的"11"
*
* @param num
*
* @return 返回最高位"11"所在的位置
*/
int find_dual1(const int num) {
int mask = (1<<1) + 1 ;
int b = -1;
for(int i = 1; i <= 30; ++i) {
if((num&mask) == mask){
b = i;
}
mask <<=1;
}
return b;
}
int find_int(const int num, const int b, const vector<int> & sum) {
int cnt = 0;
/*最高位等於b的數*/
int dual1_pos = find_dual1(num);
if(-1 == dual1_pos) {
cnt += 1;/*num self.*/
}
int next_b = b-1;
for(; next_b > dual1_pos; --next_b) {
if(num & (1 << next_b)) {
cnt += sum[next_b];
}
}
if(-1 != dual1_pos){
if(dual1_pos == b) {
cnt += sum[dual1_pos-1];
}else {
cnt += sum[dual1_pos];
cnt += sum[dual1_pos-1];
}
}
/*最高位小於b的數*/
cnt += sum[b];
return cnt;
}
int findIntegers(int num) {
int b = 0;
while(1<<(b+1) <= num) {
++b;
}
vector<int> a(b+1, 0);
a[0] = 1;
a[1] = 1;
a[2] = 1;
for(int i = 3; i <= b; ++i) {
a[i] = a[i-1] + a[i-2];
}
vector<int> sum(b+1,0);
int s = 0;
for(int i = 0; i <= b; ++i) {
s += a[i];
sum[i] = s;
}
return find_int(num, b, sum);
}
};