Learnitweb

LeetCode 38 — Count and Say

Problem Summary

The count-and-say sequence is defined as follows:

  • Term 1 is "1".
  • Each subsequent term is generated by reading aloud the digits of the previous term.
  • Reading aloud means grouping consecutive identical digits and describing them by:
<number of digits><digit>

For example:

  • "1" becomes "11"
  • "11" becomes "21"
  • "21" becomes "1211"
  • "1211" becomes "111221"

Your task:
Given an integer n, return the nth term of this sequence as a string.

Constraints
1 ≤ n ≤ 30


Understanding the Sequence

List of first few terms:

  1. "1"
  2. "11" → one 1
  3. "21" → two 1s
  4. "1211" → one 2, one 1
  5. "111221"→ one 1, one 2, two 1s
  6. "312211"

Each term depends only on the previous term.


Approach (Simple English)

To generate the nth term:

  1. Start with "1" for n = 1.
  2. For each step from 2 to n:
    • Read the previous term.
    • Count consecutive identical characters.
    • Build the new string using <count><digit>.

Why This Works

The problem is purely iterative:
each term is generated by processing characters of the previous term in order.

This gives a time complexity roughly proportional to the length of the terms.


Algorithm Steps

For each iteration:

  1. Initialize an empty StringBuilder.
  2. Scan the previous term with a pointer:
    • Count how many times the same digit repeats.
    • Append count and digit.
  3. Continue until all characters are processed.

Return the final StringBuilder as a string.


Java Code (Iterative Solution)

class Solution {
    public String countAndSay(int n) {

        String result = "1";

        for (int i = 2; i <= n; i++) {
            result = generate(result);
        }

        return result;
    }

    private String generate(String prev) {
        StringBuilder sb = new StringBuilder();

        int count = 1;
        for (int i = 1; i < prev.length(); i++) {
            if (prev.charAt(i) == prev.charAt(i - 1)) {
                count++;
            } else {
                sb.append(count);
                sb.append(prev.charAt(i - 1));
                count = 1;
            }
        }

        // Append the last group
        sb.append(count);
        sb.append(prev.charAt(prev.length() - 1));

        return sb.toString();
    }
}

Dry Run

Generate term 5:

Term 1: "1"
Term 2: read "1""11"
Term 3: read "11""21"
Term 4: read "21""1211"
Term 5: read "1211":

  • "1" → one 1 → "11"
  • "2" → one 2 → "12"
  • "11" → two 1s → "21"

Concatenate:
"11" + "12" + "21" = "111221"

So output for n = 5 is "111221".


Complexity Analysis

Let Lₙ be the length of the nth term.

Time Complexity:
O(L₁ + L₂ + … + Lₙ)
Which is acceptable because n ≤ 30.

Space Complexity:
O(Lₙ)


Edge Cases

  • n = 1 → return "1"
  • Strings with large repeating groups are handled naturally by the counting logic.
  • No tricky corner cases since input is small.