14. Look and Say Pattern

The problem can be found at the following link: ๐Ÿ”— Question Link

๐Ÿงฉ Problem Description

Given an integer n, return the nth term in the Look-and-Say Sequence, also known as the Count and Say sequence.

This sequence is built by describing the previous term in terms of the count of digits in groups of the same digit.

๐Ÿ” How It Works:

Start with "1" as the first term. To generate each subsequent term:

  • Read off the digits of the previous term.

  • For each group of consecutive identical digits, state:

    • The number of times it appears (the count),

    • Followed by the digit itself.

๐Ÿ“š Examples of the Sequence:

1           # First term
11          # One 1 โ†’ "11"
21          # Two 1s โ†’ "21"
1211        # One 2, One 1 โ†’ "1211"
111221      # One 1, One 2, Two 1s โ†’ "111221"
...

๐Ÿ“˜ Examples

Example 1:

Input: n = 5

Output: 111221

Explanation: The sequence evolves as: 1 โ†’ 11 โ†’ 21 โ†’ 1211 โ†’ 111221

Example 2:

Input: n = 3

Output: 21

Explanation: The third term is: 1 โ†’ 11 โ†’ 21

๐Ÿ”’ Constraints

  • $1 \leq n \leq 30$

โœ… My Approach

๐Ÿง  Iterative Character Grouping

We iteratively build each term in the Look-and-Say sequence by scanning the previous term and counting consecutive digits.

๐Ÿ”น Algorithm Steps:

  1. Initialize the sequence with the first term as "1".

  2. Repeat the following process from the 2nd term to the nth term:

    • Create an empty string next_term.

    • Traverse the current term:

      • Count how many times a digit repeats consecutively.

      • Append the count followed by the digit to next_term.

    • Update the current term to next_term for the next iteration.

  3. Return the final term after n - 1 transformations.

๐Ÿงฎ Time and Auxiliary Space Complexity

Metric
Complexity

Time

O(n ร— L), where L is the average length of terms in the sequence. Each of the n iterations processes a string with increasing size.

Auxiliary Space

O(L), used for building the next term at each step.

๐Ÿง  Code (C++)

class Solution {
  public:
    string countAndSay(int n) {
        string res = "1";
        for (int i = 1; i < n; ++i) {
            string temp;
            for (int j = 0; j < res.size(); ) {
                int k = j;
                while (k < res.size() && res[k] == res[j]) ++k;
                temp += to_string(k - j) + res[j];
                j = k;
            }
            res = temp;
        }
        return res;
    }
};
โšก Alternative Approaches

๐Ÿ“Š 2๏ธโƒฃ Using ostringstream for Cleaner Formatting

๐Ÿ’ก Algorithm Steps:

  1. Initialize the result as "1".

  2. Repeat the following for n-1 times:

    • Create an ostringstream to build the next sequence.

    • Traverse the current result:

      • Count consecutive identical digits.

      • Append count and digit to the stream.

    • Convert stream to string for the next iteration.

class Solution {
  public:
    string countAndSay(int n) {
        string result = "1";
        for (int i = 1; i < n; ++i) {
            ostringstream oss;
            int count = 1;
            for (int j = 1; j < result.size(); ++j) {
                if (result[j] == result[j - 1]) {
                    ++count;
                } else {
                    oss << count << result[j - 1];
                    count = 1;
                }
            }
            oss << count << result.back();
            result = oss.str();
        }
        return result;
    }
};

โœ… Why This Approach?

  • ๐Ÿงน Makes code cleaner and more readable.

  • ๐Ÿงต Uses standard ostringstream for better formatting.

๐Ÿ“ Complexity Analysis:

  • Time: O(n ร— L), where L = average length of result strings.

  • Auxiliary Space: O(L) per iteration.

๐Ÿ“Š 3๏ธโƒฃ Recursive Implementation

๐Ÿ’ก Algorithm Steps:

  1. Base case: If n == 1, return "1".

  2. Recursively get the string for n - 1.

  3. Traverse that result:

    • Count repeating digits.

    • Build the result string using count and digit.

class Solution {
  public:
    string countAndSay(int n) {
        if (n == 1) return "1";
        string prev = countAndSay(n - 1);
        string result;
        for (int i = 0; i < prev.size(); ) {
            int count = 1;
            while (i + count < prev.size() && prev[i + count] == prev[i]) ++count;
            result += to_string(count) + prev[i];
            i += count;
        }
        return result;
    }
};

โœ… Why This Approach?

  • ๐Ÿง  Clear and elegant for recursive thinkers.

  • ๐ŸŽฏ Shows the conceptual chain between n and n-1.

๐Ÿ“ Complexity Analysis:

  • Time: O(n ร— L)

  • Auxiliary Space: O(n ร— L) (due to recursion stack + strings)

๐Ÿ†š Comparison of Approaches

Approach

โฑ๏ธ Time

๐Ÿ—‚๏ธ Space

โœ… Pros

โš ๏ธ Cons

๐Ÿง  Iterative

๐ŸŸข O(n ร— L)

๐ŸŸข O(L)

Efficient, easy to follow

Manual string manipulation

๐Ÿงต ostringstream version

๐ŸŸข O(n ร— L)

๐ŸŸข O(L)

Cleaner, readable syntax

Slightly more memory due to stream

๐Ÿ” Recursive version

๐Ÿ”ธ O(n ร— L)

๐Ÿ”ธ O(n ร— L)

Short, expressive, good for interviews

โš ๏ธ Stack overflow risk for large n

โœ… Best Choice by Scenario

Scenario

Recommended Approach

๐ŸŽ๏ธ Performance-focused

๐Ÿฅ‡ Iterative (main version)

๐Ÿงผ Clean, readable formatting

๐Ÿฅˆ ostringstream version

๐Ÿ’ฌ Interviews / Conceptual Clarity

๐Ÿฅ‰ Recursive implementation

๐Ÿง‘โ€๐Ÿ’ป Code (Java)

class Solution {
    public String countAndSay(int n) {
        String result = "1";
        for (int i = 2; i <= n; i++) {
            StringBuilder temp = new StringBuilder();
            int count = 1;
            for (int j = 1; j < result.length(); j++) {
                if (result.charAt(j) == result.charAt(j - 1)) {
                    count++;
                } else {
                    temp.append(count).append(result.charAt(j - 1));
                    count = 1;
                }
            }
            temp.append(count).append(result.charAt(result.length() - 1));
            result = temp.toString();
        }
        return result;
    }
}

๐Ÿ Code (Python)

class Solution:
    def countAndSay(self, n: int) -> str:
        result = "1"
        for _ in range(n - 1):
            i = 0
            new_result = ""
            while i < len(result):
                count = 1
                while i + 1 < len(result) and result[i] == result[i + 1]:
                    count += 1
                    i += 1
                new_result += str(count) + result[i]
                i += 1
            result = new_result
        return result

๐Ÿง  Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: ๐Ÿ“ฌ Any Questions?. Letโ€™s make this learning journey more collaborative!

โญ If you find this helpful, please give this repository a star! โญ


๐Ÿ“Visitor Count

Last updated