Non-negative Integers without Consecutive Ones - Complete Solution Guide
Non-negative Integers without Consecutive Ones is LeetCode problem 600, a Hard level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
Given a positive integer n , return the number of the integers in the range [0, n] whose binary representations do not contain consecutive ones. Example 1: Input: n = 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. Example 2: Input: n = 1 Output: 2 Example 3: Input: n = 2 Output: 3 Constra
Detailed Explanation
The problem asks us to count the number of non-negative integers within the range [0, n] (inclusive) that do not have consecutive 1s in their binary representation. For instance, if n = 5, the binary representations are 0 (0), 1 (1), 2 (10), 3 (11), 4 (100), and 5 (101). Only 3 (11) has consecutive 1s, so the answer is 5 (the count of the others). The input n is a positive integer between 1 and 10^9.
Solution Approach
The solution leverages the Fibonacci sequence to count the number of valid binary strings of different lengths that are less than or equal to the binary representation of 'n'. The algorithm iterates through the bits of 'n' from left to right (most significant bit to least significant bit). If the current bit is '1', we add fib[k] to the answer, where k is the number of remaining bits. A crucial condition is checked if the previous bit was also '1'. If so, it means any further numbers generated would be greater than 'n' (because of consecutive ones where they shouldn't be), so we return the answer immediately. Otherwise, if the current bit is '0', we simply set the 'prev_bit_is_one' flag to false.
Step-by-Step Algorithm
- Step 1: Convert the integer 'n' to its binary string representation.
- Step 2: Create an array 'fib' to store the Fibonacci sequence. Initialize fib[0] = 1 and fib[1] = 2. Then, calculate fib[i] = fib[i-1] + fib[i-2] for i from 2 to 30.
- Step 3: Initialize a variable 'ans' to 0, which will store the count of valid integers.
- Step 4: Initialize a boolean variable 'prev_bit_is_one' to false, to track if the previous bit was a '1'.
- Step 5: Iterate through the binary string from left to right (most significant bit to least significant bit).
- Step 6: For each bit at index 'i', calculate 'k' as length - 1 - i (number of remaining bits).
- Step 7: If the bit at index 'i' is '1':
- a. Add fib[k] to 'ans'.
- b. If 'prev_bit_is_one' is true, return 'ans' (because having consecutive 1's means we've exceeded n and all remaining numbers will exceed n as well)
- c. Set 'prev_bit_is_one' to true.
- Step 8: If the bit at index 'i' is '0', set 'prev_bit_is_one' to false.
- Step 9: After the loop finishes, return 'ans + 1'. Adding 1 accounts for the integer 0, which always satisfies the condition.
Key Insights
- Insight 1: The problem can be efficiently solved using dynamic programming combined with the Fibonacci sequence. The number of binary strings of length 'k' without consecutive 1s can be derived from Fibonacci numbers.
- Insight 2: We can build the solution by iterating through the bits of the binary representation of the given number 'n'. If we encounter a '1', we can add the number of valid strings of shorter length to our count. We must also handle the case of consecutive 1's.
- Insight 3: Pre-computing the Fibonacci sequence up to a certain length (31, since n <= 10^9 fits within 31 bits) helps to optimize the calculation during the iteration.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(1)
Topics
This problem involves: Dynamic Programming.
Companies
Asked at: Pocket Gems.