Start learning free

LESSON 340 OF 409 · FREE CODING INTERVIEW QUESTIONS

Binary Strings with at most K Consecutive Ones in C++ (Time Complexity: O(N*K))

Practice O(n * k) Read the full explanation

Given two non-negative integers N and K, return the number of binary strings of length N with at most K consecutive ones

Example:

Input: N = 4, K = 2
Output: 13
Explanation: [
    "0000",
    "0001",
    "0010",
    "0011",
    "0100",
    "0101",
    "0110",
    "1000",
    "1001",
    "1010",
    "1011",
    "1100",
    "1101",
]
"0111", "1110" and "1111" are not valid because they have more than 2 consecutive ones
Notes: K <= N <= 30
STEP 1 OF 9
    Ctrl + Enter to check

    C++ · FREE CODING INTERVIEW QUESTIONS

    Binary Strings With At Most K Consecutive Ones in C++, explained

    Understanding the Problem

    The core challenge of this problem is to generate all possible binary strings of length N and count those that have at most K consecutive ones. This problem is significant in various fields such as coding theory, data compression, and error detection.

    Potential pitfalls include misunderstanding the constraint of "at most K consecutive ones" and not efficiently generating or counting the valid strings.

    Approach

    To solve this problem, we can use dynamic programming (DP). The idea is to build a DP table where dp[i][j] represents the number of valid binary strings of length i that end with exactly j consecutive ones.

    We can start by initializing the base cases and then fill the DP table using the following transitions:

    • If the current string ends with a '0', the previous part of the string can be any valid string of length i-1.
    • If the current string ends with 'j' consecutive '1's, the previous part of the string must be a valid string of length i-j ending with '0'.

    Algorithm

    Here is a step-by-step breakdown of the algorithm:

    1. Initialize a DP table dp with dimensions (N+1) x (K+1) to store the number of valid strings.
    2. Set the base case: dp[0][0] = 1 (an empty string is a valid string).
    3. Iterate over the length of the string from 1 to N.
    4. For each length, iterate over the number of consecutive ones from 0 to K.
    5. Update the DP table based on the transitions described above.
    6. Sum up all the valid strings of length N to get the final result.

    Code Implementation

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    // Function to count binary strings of length N with at most K consecutive ones
    int countBinaryStrings(int N, int K) {
        // DP table to store the number of valid strings
        vector<vector<int>> dp(N + 1, vector<int>(K + 1, 0));
        
        // Base case: an empty string is a valid string
        dp[0][0] = 1;
        
        // Fill the DP table
        for (int i = 1; i <= N; ++i) {
            for (int j = 0; j <= K; ++j) {
                // If the current string ends with '0'
                for (int l = 0; l <= K; ++l) {
                    dp[i][0] += dp[i - 1][l];
                }
                // If the current string ends with 'j' consecutive '1's
                if (j > 0) {
                    dp[i][j] = dp[i - 1][j - 1];
                }
            }
        }
        
        // Sum up all valid strings of length N
        int result = 0;
        for (int j = 0; j <= K; ++j) {
            result += dp[N][j];
        }
        
        return result;
    }
    
    int main() {
        int N = 4, K = 2;
        cout << "Number of binary strings of length " << N << " with at most " << K << " consecutive ones: " << countBinaryStrings(N, K) << endl;
        return 0;
    }
    

    Complexity Analysis

    The time complexity of this approach is O(N * K) because we fill a DP table of size (N+1) x (K+1). The space complexity is also O(N * K) due to the storage required for the DP table.

    Edge Cases

    Potential edge cases include:

    • N = 0: The only valid string is the empty string.
    • K = 0: Only strings with no consecutive ones are valid.

    These cases are handled by the base case and the DP transitions.

    Testing

    To test the solution comprehensively, consider the following test cases:

    • N = 4, K = 2: Expected output is 13.
    • N = 5, K = 1: Expected output is 8.
    • N = 3, K = 0: Expected output is 1.

    Use a variety of test cases, from simple to complex, to ensure the solution is robust.

    Thinking and Problem-Solving Tips

    When approaching such problems, consider breaking down the problem into smaller subproblems and using dynamic programming to solve them efficiently. Practice similar problems to develop a deeper understanding of DP techniques.

    Conclusion

    In this blog post, we discussed how to count binary strings of length N with at most K consecutive ones using dynamic programming. We covered the problem definition, approach, algorithm, code implementation, complexity analysis, edge cases, and testing. Understanding and solving such problems is crucial for improving problem-solving skills and preparing for coding interviews.

    Additional Resources

    For further reading and practice, consider the following resources:

    Keep going with C++About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free