Daily question: 600. Non negative integers without continuous 1

Keywords: C++ Algorithm

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:

Binary length
n=1n=2n=3n=4
00000000001000
10100100011001
1001000101010
1101100111011
10001001100
10101011101
11001101110
11101111111
2358

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;
    }

};

Posted by Quilmes on Sun, 21 Nov 2021 02:01:15 -0800