Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

38. Count and Say - Leetcode Solution

Code Implementation

class Solution:
    def countAndSay(self, n: int) -> str:
        result = "1"
        for _ in range(n - 1):
            prev = result
            result = ""
            i = 0
            while i < len(prev):
                count = 1
                while i + 1 < len(prev) and prev[i] == prev[i + 1]:
                    i += 1
                    count += 1
                result += str(count) + prev[i]
                i += 1
        return result
      
class Solution {
public:
    string countAndSay(int n) {
        string result = "1";
        for (int k = 1; k < n; ++k) {
            string prev = result;
            result = "";
            int i = 0;
            while (i < prev.size()) {
                int count = 1;
                while (i + 1 < prev.size() && prev[i] == prev[i + 1]) {
                    ++i;
                    ++count;
                }
                result += to_string(count) + prev[i];
                ++i;
            }
        }
        return result;
    }
};
      
class Solution {
    public String countAndSay(int n) {
        String result = "1";
        for (int k = 1; k < n; k++) {
            StringBuilder sb = new StringBuilder();
            int i = 0;
            while (i < result.length()) {
                int count = 1;
                while (i + 1 < result.length() && result.charAt(i) == result.charAt(i + 1)) {
                    i++;
                    count++;
                }
                sb.append(count).append(result.charAt(i));
                i++;
            }
            result = sb.toString();
        }
        return result;
    }
}
      
var countAndSay = function(n) {
    let result = "1";
    for (let k = 1; k < n; k++) {
        let prev = result;
        result = "";
        let i = 0;
        while (i < prev.length) {
            let count = 1;
            while (i + 1 < prev.length && prev[i] === prev[i + 1]) {
                i++;
                count++;
            }
            result += count.toString() + prev[i];
            i++;
        }
    }
    return result;
};
      

Problem Description

The "Count and Say" problem asks you to generate the nth term in a specific sequence of numbers. The sequence starts with "1", and each subsequent term is constructed by describing the previous term in terms of consecutive digits. For example, the first few terms are:

  • 1st term: "1"
  • 2nd term: "11" (one 1)
  • 3rd term: "21" (two 1s)
  • 4th term: "1211" (one 2, then one 1)
  • 5th term: "111221" (one 1, one 2, two 1s)

Given an integer n, your task is to return the nth term of this sequence as a string.

  • There is only one valid sequence for each n.
  • The sequence is built iteratively; each term is derived from the previous one, and you cannot skip terms.

Thought Process

At first glance, the problem looks like it requires generating a string based on a simple pattern. However, the key is to realize that each term is not just a transformation of numbers, but a "verbal description" of the previous term's digits.

A brute-force approach might involve manually building each term by counting consecutive digits and appending the count and digit to a new string. This is manageable for small n, but we need to ensure our method is efficient and can handle larger values.

As we analyze further, we notice that:

  • Each term depends solely on the immediate previous term.
  • We never need to store the whole sequence, just the current and previous term.
  • We can process each term by iterating through its characters, counting consecutive identical digits, and building the new string as we go.
This leads us to a straightforward iterative approach, which is both simple and efficient for the problem's constraints.

Solution Approach

Let's break down the solution step by step:

  1. Initialization: Start with the string "1" as the first term.
  2. Iterative Construction:
    • For each term from 2 up to n, we generate the next term by reading the previous term.
    • Use a pointer or index to traverse the previous term.
    • For each group of consecutive identical digits, count how many times the digit appears in a row.
    • Append the count followed by the digit to a new string representing the current term.
    • Repeat this process until the end of the previous term is reached.
  3. Return the Result: After generating the nth term, return it as a string.

This method is efficient because:

  • We only ever need to keep track of the current and previous terms, saving memory.
  • Each term is generated in a single pass through the previous term.

Example Walkthrough

Let's walk through generating the 5th term (n = 5):

  1. Start: result = "1"
  2. 2nd term: Read "1" → one 1 → "11"
  3. 3rd term: Read "11" → two 1s → "21"
  4. 4th term: Read "21"
    • one 2 → "12"
    • one 1 → "11"
    • Combined: "1211"
  5. 5th term: Read "1211"
    • one 1 → "11"
    • one 2 → "12"
    • two 1s → "21"
    • Combined: "111221"

So, for n = 5, the output is "111221".

Time and Space Complexity

Brute-force Approach:

  • Would involve storing all previous terms, leading to higher memory usage.
  • Each term's length grows, so processing each term could become expensive.
Optimized Iterative Approach:
  • Time Complexity: O(M), where M is the length of the nth term. Each character is processed once per term.
  • Space Complexity: O(M), since we only store the current and previous terms.

The length of each term grows exponentially, but for reasonable n (as in Leetcode constraints), this approach is efficient.

Summary

The "Count and Say" problem is a classic example of sequence construction based on simple rules. By iteratively describing the previous term, we can build each new term efficiently. The key insight is to process the string in a single pass, counting consecutive digits, and to build only what we need for the next term. This results in a simple, elegant, and efficient solution that is easy to implement in any major programming language.