LeetCode 38: Count and Say Solution in Python Explained

Problem Statement

Section link icon

LeetCode 38, Count and Say, is a medium-level problem where you’re given an integer n (1 ≤ n ≤ 30). Your task is to return the nth term of the "count-and-say" sequence. The sequence starts with "1", and each subsequent term is generated by describing the previous term: count consecutive digits and say them. For example, "1" becomes "11" (one 1), "11" becomes "21" (two 1s), and so on.

Constraints

  • 1 <= n <= 30: Input is between 1 and 30.

Example

Input: n = 1
Output: "1"
Explanation: First term is "1".

Input: n = 2
Output: "11"
Explanation: "1" -> one 1 -> "11".

Input: n = 4
Output: "1211"
Explanation: "1" -> "11" -> "21" -> "1211" (one 2, one 1).

Understanding the Problem

Section link icon

How do you solve LeetCode 38: Count and Say in Python? For n = 4, the sequence is: "1" → "11" → "21" → "1211". Each term describes the previous by counting consecutive digits and stating them (e.g., "21" is "two 1s" → "1211"). We’ll explore two approaches: an Iterative Solution (optimal and primary) and an Alternative with Recursion (elegant but less efficient). The iterative method builds each term step-by-step, making it straightforward.

Solution 1: Iterative Approach (Primary)

Section link icon

Explanation

Start with "1" and iteratively generate each term up to n. For each term, scan the string, count consecutive digits, and build the next string by appending the count and digit.

Here’s a flow for n = 4:

1: "1"
2: "11" (one 1)
3: "21" (two 1s)
4: "1211" (one 2, one 1)
  1. Base Case.
  • If n = 1, return "1".
  1. Iterate n-1 Times.
  • Generate each term from the previous.
  1. Count and Say.
  • Count consecutive digits, append count and digit.
  1. Return nth Term.

Step-by-Step Example

Example 1: n = 4

We need "1211".

  • Goal: Generate 4th term.
  • Result for Reference: "1211".
  • Start: curr = "1", n = 4.
  • Step 1: n = 1, return "1" if done, else proceed.
  • Step 2: i = 2, process "1".
    • Count = 1, digit = "1", next = "11".
  • Step 3: i = 3, process "11".
    • Count = 2, digit = "1", next = "21".
  • Step 4: i = 4, process "21".
    • Count = 1, digit = "2", append "12".
    • Count = 1, digit = "1", append "11", next = "1211".
  • Finish: Return "1211".

Example 2: n = 3

We need "21".

  • Start: curr = "1".
  • Step 1: i = 2, "1" → "11".
  • Step 2: i = 3, "11" → "21".
  • Finish: Return "21".

How the Code Works (Iterative)

Here’s the Python code with line-by-line explanation:

def countAndSay(n: int) -> str:
    # Line 1: Base case
    if n == 1:
        return "1"

    # Line 2: Start with first term
    curr = "1"

    # Line 3: Generate terms up to n
    for _ in range(n - 1):
        # Line 4: Build next term
        next_str = ""
        count = 1
        # Line 5: Scan current string
        for i in range(len(curr)):
            # Line 6: If last char or different from next
            if i == len(curr) - 1 or curr[i] != curr[i + 1]:
                next_str += str(count) + curr[i]
                count = 1
            else:
                # Line 7: Increment count for consecutive digits
                count += 1
        # Line 8: Update current term
        curr = next_str

    # Line 9: Return nth term
    return curr

Alternative: Recursive Approach

Section link icon

Explanation

Recursively define the nth term as the "count and say" of the (n-1)th term, with base case n = 1 returning "1". Process the previous term to build the next.

  1. Base Case.
  2. Recurse.
  • Get (n-1)th term, count and say it.

3. Return Result.

Step-by-Step Example (Alternative)

For n = 4:

  • Goal: "1211".
  • Step 1: countAndSay(4) → countAndSay(3).
  • Step 2: countAndSay(3) → "21" from countAndSay(2).
  • Step 3: countAndSay(2) → "11" from countAndSay(1).
  • Step 4: countAndSay(1) → "1".
  • Step 5: "1" → "11" → "21" → "1211".
  • Finish: Return "1211".

How the Code Works (Recursive)

def countAndSayRecursive(n: int) -> str:
    # Line 1: Base case
    if n == 1:
        return "1"

    # Line 2: Get previous term
    prev = countAndSayRecursive(n - 1)

    # Line 3: Build next term
    result = ""
    count = 1
    for i in range(len(prev)):
        if i == len(prev) - 1 or prev[i] != prev[i + 1]:
            result += str(count) + prev[i]
            count = 1
        else:
            count += 1

    # Line 4: Return nth term
    return result

Complexity

  • Iterative:
    • Time: O(2^n) – Each term roughly doubles in length (exponential growth).
    • Space: O(2^n) – Size of the final string.
  • Recursive:
    • Time: O(2^n) – Same growth pattern.
    • Space: O(2^n) – String size plus O(n) recursion stack.

Efficiency Notes

Both are O(2^n) due to the sequence’s exponential growth (e.g., "1211" → "111221" → "312211"). Iterative is more space-efficient (no stack), while Recursive is elegant but uses extra memory.

Key Insights

Tips to master LeetCode 38:

  • Count Consecutive: Group same digits, count them.
  • String Building: Append count + digit systematically.
  • Growth Awareness: Terms get long fast—handle efficiently.

Additional Example

Section link icon

For n = 5:

  • Goal: "111221".
  • Iterative: "1" → "11" → "21" → "1211" → "111221".
  • Result: "111221".

Edge Cases

Section link icon
  • n = 1: Return "1".
  • n = 2: Return "11".
  • Large n: e.g., n = 30, expect very long strings.

Final Thoughts

Section link icon

The Iterative solution is a solid pick for LeetCode 38 in Python—straightforward, efficient, and easy to follow. For a related challenge, try LeetCode 37: Sudoku Solver to flex your problem-solving muscles! Ready to count and say? Solve LeetCode 38 on LeetCode now and test it with n = 5 or n = 10 to see the sequence grow. Jump in and master it!