Skip to main content

Count Good Strings - Solution & Explanation

Hard4 min read
Practice this problem

Problem Statement

You are given an integer n.

A string is considered good if it consists only of the characters 'a' and 'b', and one of the following holds:

  • It contains exactly one distinct character, and its length is odd.
  • It can be written as s = s1 + s2, where s1 and s2 are non-empty good strings, and the last character of s1 is different from the first character of s2.

Return the number of good strings of length n, modulo 109 + 7.

Here, + denotes string concatenation.

 

Example 1:

Input: n = 4

Output: 6

Explanation:

  • The good strings are "aaab", "abbb", "baaa", "bbba", "abab", and "baba".
  • For example, "aaab" = "aaa" + "b". Both parts are good because each contains one distinct character and has odd length, and their characters at the boundary are different.
  • Also, "ab" = "a" + "b" is good, so "abab" = "ab" + "ab" is good because the boundary characters are different.
  • Thus, the answer is 6.

Example 2:

Input: n = 3

Output: 4

Explanation:

The good strings are "aaa", "bbb", "aba", and "bab". Thus, the answer is 4.

Example 3:

Input: n = 2

Output: 2

Explanation:

The good strings are "ab" and "ba". Thus, the answer is 2.

 

Constraints:

  • 1 <= n <= 1015

Approach Overview

Problem Overview: You are given a length constraint and a rule that decides whether a string is good. Count how many strings satisfy the rule, modulo 10^9 + 7. Brute force fails because the number of candidate strings grows exponentially with length.

Approach 1: Brute Force Enumeration (O(2^n * n) time, O(n) space)

Generate every string of the target length over the allowed alphabet with recursion or backtracking. For each complete string, run the goodness check, which scans the string once. This is correct because it touches every candidate, but the candidate count doubles with each extra character. Use it only to validate outputs on small inputs while you derive the recurrence.

Approach 2: Memoized Recursion on State (O(n * k) time, O(n * k) space)

Notice that whether a prefix can still lead to a good string depends only on a small state, such as the current length and a few counters that track the rule. Define dp(pos, state) as the number of valid completions from that point. Cache results in a hash map or 2D array so each state is computed once. This turns exponential enumeration into a polynomial number of distinct subproblems. It is the fastest route to a correct answer when the state space is clear, and it is easy to verify against the brute force. Review the dynamic programming patterns if the state transitions feel unclear.

Approach 3: Bottom-Up DP with Prefix Sums (O(n) time, O(1) extra space)

Replace recursion with an iterative table that builds counts from length 0 up to the target. Each new length is derived from earlier lengths by adding a fixed set of transitions, and you can accumulate them with a running prefix sum over a window of previous values instead of summing from scratch. This removes recursion overhead and keeps only the last few values, which is why it is the expected final answer. Take the modulo after every addition to avoid overflow. For counting problems over ranges of lengths, the prefix sum technique keeps the update constant time per step.

Recommended for interviews: Interviewers expect you to start with brute force to show you understand the search space, then move to memoized recursion to reveal the state. The bottom-up version with prefix sums demonstrates the skill they are testing. Explain the state definition clearly before you write any code, because most candidates lose time on the transitions rather than the final loop. Practice related string counting problems to build the habit of identifying the minimal state.

Solutions for this problem are being prepared.

Try solving it yourself

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Brute Force EnumerationO(2^n * n)O(n)Small inputs for validating other solutions
Memoized RecursionO(n * k)O(n * k)When the state is clear and you want a quick correct solution
Bottom-Up DP with Prefix SumsO(n)O(1) extraGeneral case and interviews, large n

Video Solution

LeetCode 4073 | Count Good Strings | Fibonacci | Java | Hindi

Code Kage24:59105 views

Frequently Asked Questions

Is Count Good Strings easy or hard?
Count Good Strings is rated Hard because the difficulty lies in defining the correct DP state, not in the code itself. Once you identify the state and transitions, the implementation is short and runs in linear time.
How to solve Count Good Strings in O(n)?
Define a DP state that captures everything a prefix needs to know about the good-string rule. Iterate from length 0 to n, compute each new value from earlier values using a running prefix sum, and take the result modulo 10^9 + 7 after every addition. Return the value for the target length.
Count Good Strings Python and Java solution?
Both languages use the same bottom-up DP loop. In Python, use integer arithmetic with the modulo applied after each update, and in Java use long to avoid overflow before taking the modulo. The full working code for both is available in the solution tabs on FleetCode.
What is the best approach for Count Good Strings?
The best approach is bottom-up dynamic programming with prefix sums. It builds counts length by length, keeps only the few values needed for the next step, and runs in O(n) time with O(1) extra space. Start from a memoized recursion if the state transitions are not yet clear.
What data structure is used in Count Good Strings?
The main structure is a one-dimensional or two-dimensional DP array, or a hash map for memoization. The optimal version uses only a few scalar variables to store the last values, along with a running prefix sum. No heavy data structures like trees or heaps are required.
What is the time complexity of Count Good Strings?
The optimal solution runs in O(n) time, where n is the target length, because each length is computed once in constant time using prefix sums. Brute force enumeration is exponential, O(2^n * n), and memoized recursion is O(n * k) where k is the number of states per position.
Is Count Good Strings asked at Google, Amazon, or Meta?
Count Good Strings is a counting and dynamic programming problem, and similar string-counting questions appear in interviews at large tech companies. Check company-tagged question lists on FleetCode for the latest reported frequency, since this problem is tagged General on the platform.

Ready to solve this problem?

Practice Count Good Strings with our built-in code editor and test cases.

Practice on FleetCode