Title:
Given a positive integer n, find a non negative integer less than or equal to n whose binary representation does not contain Continuous 1 Number of.
Example 1:
Input: 5
Output: 5
Explanation:
The following is a nonnegative integer < = 5 with the corresponding binary representation:
0 : 0
1 : 1
2 : 10
3 : 11
4 : 100
5 : 101
Among them, only integer 3 violates the rule (there are two consecutive ones), and the other 5 satisfy the rule.
Description: 1 < = n < = 10 ^ 9
Idea: (dynamic programming)
Set an array: expressed by f(i) as the number of binary numbers (range i 0~~i 1) with length i without continuous 1 (similar to Fibonacci sequence)
It can be observed that:
n=1 | n=2 | n=3 | n=4 | ||
---|---|---|---|---|---|
0 | 00 | 000 | 0000 | 1000 | |
1 | 01 | 001 | 0001 | 1001 | |
10 | 010 | 0010 | 1010 | ||
11 | 011 | 0011 | 1011 | ||
100 | 0100 | 1100 | |||
101 | 0101 | 1101 | |||
110 | 0110 | 1110 | |||
111 | 0111 | 1111 | |||
2 | 3 | 5 | 8 |
f(i) =f(i-1)+f(i-2) When n=0, set it to 1, that is, f (0) = 1;
To find all the numbers that meet the conditions (i.e. no weight and no leakage), you can divide the numbers in a given range into several stages to see the numbers that meet the conditions in each stage.
Start to convert a number into binary and scan from the most significant bit (left - > right). Whenever a 1 is encountered, i.e. (1 *****, there are k binary bits after 1, and each * can be 1 or 0), f(k) needs to be increased to meet the total number count of binary numbers without continuous 1, because we can put a '0' on this number, Any string with a valid len gt h of K is placed after it; After that, we continue to cycle through the rest of the situation, that is, we put a '1' on this digit. If we find a continuous 1, we exit the loop and return the answer. At the end of the loop, we return count+1, including the number n itself.
For example, if n is 10010110, then you need to find a number smaller than N and without continuous 1:
1. We only change the first significant bit 1 to 0. The number after this 1 will be smaller than n. the largest number is the number whose last 7 bits are "1". These numbers can be represented by the range 00000000-01111111, in which the number of binary numbers satisfying that there is no continuous 1 is f(7).
2. We only change the second significant bit 1 to 0, and the number after this 1 will be smaller than n. the largest number is the number whose last four bits are "1". These numbers can be expressed in the range of 10000000-10001111, and the number of numbers is 0000-1111, in which the number of binary numbers satisfying the non continuous 1 is f(4).
3. We only change the third significant bit 1 to 0. The number after this 1 will be smaller than n. the largest number is the number whose last two bits are "1". These numbers can be expressed in the range of 10010000-10011. The number of numbers is 00 ~ 11, in which the number of binary numbers that do not contain continuous 1 is f(2).
4. We only change the fourth significant bit 1 to 0. The number after this 1 will be smaller than n, in which the largest number is the number with the last bit of "1". These numbers can be expressed in the range 10010100-10010101. The number of numbers is 0 ~ 1, in which the number of binary numbers that do not contain continuous 1 is f(1).
Note: in the binary representation of numbers, there are several 1s (for example, there are k 1s), and here there are several (k) steps.
The next operation needs to transform the binary number 1001011x, but 1001011x has a continuous 1, which is illegal, so it does not enter the count.
Illustration:
code:
(here, binary numbers are converted into strings, and 32 length strings are used to store the values of Fibonacci sequence, which consumes too much memory)
class Solution { public: //Function converts a number to a binary string string binaryStr(int num) { //Defines a string to accept the converted binary string string st = ""; while (num>0) { //Convert the calculated number to the corresponding character '0' or '1' char c = num % 2 + '0'; st.push_back(c);//Here is the binary low order in front and the high order in back num /= 2; } //Reverse, because we want the high position in the front and the low position in the back reverse(st.begin(), st.end()); return st; } //Finally, I want to return int num=0; int findIntegers(int n) { //Initialize Fibonacci sequence //int 32 bit vector<int> f(32); f[0] = 1; f[1] = 2; for (int i = 2; i < 32; i++) { f[i] = f[i - 1] + f[i - 2]; } string str1 = binaryStr(n); for (int i = 0; i < str1.size(); i++) { if (str1[i] == '0') continue; num += f[str1.size() - 1 - i]; if (i != 0 && str1[i - 1] == '1') return num; } //Plus 1 means that n itself is also a return num + 1; } };
Second Edition: write a function to find each value of Fibonacci sequence, and use variable k to represent the binary digits after significant digit 1
class Solution { public: //Finding Fibonacci sequence function int feiB(int num) { int f_1 = 1, f_2 = 2, f_3 = 3; if (num == 0) return f_1; if (num == 1)return f_2; for (int i = 2; i <= num; i++){ f_3 = f_1 + f_2; f_1 = f_2; f_2 = f_3; } return f_3; } int findIntegers(int n) { //Finally, I want to return int num = 0; //Record the first digit, because the first two consecutive digits are 1, so you don't have to look at it later int preBit = 0; //The maximum number of int data is 2 ^ 31-1. There are 31 digits at most, and 32 digits are not available int k = 30; while (k>=0) { //1 shifts 30 bits to the left, that is, 30 zeros behind 1 //Judge whether the k-bit is 1 if (n & (1 << k)) { //cout << k<<endl;; num += feiB(k); if (preBit) return num; preBit = 1; } else { preBit = 0; } k--; } return num + 1; } };