Start learning free

LESSON 306 OF 338 · DYNAMIC PROGRAMMING

Binary Strings of Given Length in Go: A First DP Table

Practice O(n) Read the full explanation

Given a non-negative integer N return the number of binary strings of length N

Example:

Input: N = 3
Output: 8
Explanation: [
    "000",
    "001",
    "010",
    "011",
    "100",
    "101",
    "110",
    "111"
]
Notes: N <= 30
STEP 1 OF 5
    Ctrl + Enter to check

    GO · DYNAMIC PROGRAMMING

    Binary Strings Of Given Length in Go, explained

    Problem overview

    The function countBinaryStrings takes an int n and returns how many binary strings of length n exist: strings made only of the characters 0 and 1. For n = 3 the answer is 8, and the eight strings are 000, 001, 010, 011, 100, 101, 110 and 111. The lesson's notes say n is at most 30.

    Approach: extend shorter strings by one bit

    Listing all the strings and counting them would work for small n, but their number grows fast. Counting is easier than listing: every string of length i is a string of length i - 1 followed by one more bit. That bit is either 0 or 1, so each shorter string extends in exactly two ways, and different shorter strings (or different bits) never produce the same longer string. The count of length i is therefore twice the count of length i - 1.

    This is the pattern of dynamic programming: define a table where dp[i] is the answer for size i, fill in a starting value, and compute each later entry from the earlier ones. Here the starting value is dp[1] = 2, since the only strings of length 1 are "0" and "1".

    Step by step

    1. Create the table. dp := make([]int, n+1) makes a slice of n + 1 zeros, so the indices 0 to n exist and dp[i] can hold the count for length i.
    2. Set the base case: dp[1] = 2.
    3. Loop from 2 to n inclusive. Using i <= n makes the loop reach n itself. Filling in increasing order guarantees that dp[i-1] is ready when dp[i] needs it.
    4. Double the previous entry: dp[i] = dp[i-1] * 2.
    5. Return dp[n], the count for the full length.

    The solution in Go

    func countBinaryStrings(n int) int {
        dp := make([]int, n+1)
        dp[1] = 2
        for i := 2; i <= n; i++ {
            dp[i] = dp[i-1] * 2
        }
        return dp[n]
    }
    

    The Go details worth a closer look:

    • make([]int, n+1). It builds a slice with length n + 1 and every element set to the zero value of int, which is 0. The table could not be an array here, because an array's size must be a constant known at compile time.
    • The only loop is for. Go has no while. The three-part form init; condition; post works as in C, without parentheses, and the braces are required.
    • := declares and infers. dp := make(...) declares dp with the slice type. Declaring a variable and never using it is a compile error in Go.
    • Room to grow. int is 64 bits in Go 1.22 on 64-bit systems, so 2^30, the largest answer, which is 1073741824, fits with a wide margin.

    Because the answer is just 2 to the power n, a shortcut exists: 1 << n shifts a 1 left by n bits. The table makes the recurrence visible, which is the point of the exercise, and the same shape returns in the harder lessons that follow.

    Complexity

    Time: O(n), one loop with a constant amount of work per step. Space: O(n) for the table. Since each entry only reads the one before it, a single running variable would reduce the space to O(1).

    Edge cases and common mistakes

    • n = 1. The loop does not run, and the function returns dp[1], which is 2.
    • n = 0. There is exactly one string of length 0, the empty string, so the mathematically right answer is 1. This solution does not handle it: dp has only index 0, and the assignment dp[1] = 2 panics with an index out of range error. The lesson's notes give no promise about 0, so if you need it, add an early if n == 0 { return 1 } or start the table at dp[0] = 1.
    • Making the table too small. make([]int, n) has no index n, and reading dp[n] panics.
    • Using i < n. The loop stops one entry early and dp[n] is left at 0.
    • Adding instead of doubling. dp[i-1] + 1 grows linearly; every shorter string has two extensions, not one.

    Testing

    • n = 1 gives 2.
    • n = 3 gives 8.
    • n = 10 gives 1024.
    • n = 30 gives 1073741824.
    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free