Open In App

Look-and-Say Sequence

Last Updated : 10 May, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Find the nth term in Look-and-say (Or Count and Say) Sequence. The look-and-say sequence is the sequence of the below integers: 1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, ... 

How is the above sequence generated? 
The nth term is generated by reading (n-1)th term.

  • The first term is "1"
  • Second term is "11", generated by reading first term as "One 1" (There is one 1 in previous term)
  • Third term is "21", generated by reading second term as "Two 1"
  • Fourth term is "1211", generated by reading third term as "One 2 One 1" and so on

Examples: 

Input: n = 3
Output: 21
Explanation: The 3rd term of the sequence is 21

  • 1st term: 1
  • 2nd term: one 1 -> 11
  • 3rd term: two 1s -> 21

Input: n = 4
Output: 1211
Explanation: The 4th term of the sequence is 1211

  • 1st term: 1
  • 2nd term: one 1 -> 11
  • 3rd term: two 1s -> 21
  • 4th term: one 2 one 1 -> 1211

Input: n = 1
Output: 1
Explanation: The first term of the sequence is 1

Using Recursive - O(2^n) Time and O(n + 2^n) Space

Idea is to recursively call for n-1 to generate the previous term. Then we build the nth or current term using the (n-1)th or previous term

How to build current term using previous? To generate a term using the previous term, we scan the previous term. While scanning a term, we simply keep track of the count of all consecutive characters. For a sequence of the same characters, we append the count followed by the character to generate the next term.

Step by Step Algorithm:

  • Call the function recursively to get the (n-1)th term : prev = countAndSay(n - 1)
  • Initialize res = "" and count = 1.
  • Loop through the prev string from index 1:
  • If prev[i] == prev[i - 1], increment count. Else: append count and prev[i - 1] to result and reset count = 1
  • After the loop, append the count of last character followed by the last character. Note that in the loop, we process previous character, so the last character has to be processed separately.
C++
#include <bits/stdc++.h>
using namespace std;

// Helper function to generate the next term 
// in the sequence from the previous one
string nextTerm(string& prev) {
    string curr = "";
    int count = 1;
    
    for (int i = 1; i < prev.length(); i++) {
        
        // Keep Counting while same
        if (prev[i] == prev[i - 1]) {
            count++;
            
        // If a different character found, appemd
        // the count of previous character along
        // with the character itself
        } else {
            curr += to_string(count) + prev[i - 1];
            count = 1;
        }
    }
    
    // Append the last character's count and the
    // last character
    curr += to_string(count) + prev.back();
    
    return curr;
}

// Recursive function to return the nth term
string countAndSay(int n) {
    
    // Base case
    if (n == 1)
        return "1";
    
    // Recursively get the previous term
    string prev = countAndSay(n - 1);
    
    // Get the n-th term using (n-1)th
    return nextTerm(prev);
}

// Driver code
int main() {
    int n = 5;
    cout << countAndSay(n) << endl;
    return 0;
}
Java
// Helper function to generate the next term 
// in the sequence from the previous one
class GfG {
    public static String nextTerm(String prev) {
        StringBuilder curr = new StringBuilder();
        int count = 1;
        
        for (int i = 1; i < prev.length(); i++) {
            
            // Keep Counting while same
            if (prev.charAt(i) == prev.charAt(i - 1)) {
                count++;
                
            // If a different character found, append
            // the count of previous character along
            // with the character itself
            } else {
                curr.append(count).append(prev.charAt(i - 1));
                count = 1;
            }
        }
        
        // Append the last character's count and the
        // last character
        curr.append(count).append(prev.charAt(prev.length() - 1));
        
        return curr.toString();
    }
    
    // Recursive function to return the nth term
    public static String countAndSay(int n) {
        
        // Base case
        if (n == 1)
            return "1";
        
        // Recursively get the previous term
        String prev = countAndSay(n - 1);
        
        // Get the n-th term using (n-1)th
        return nextTerm(prev);
    }
    
    // Driver code
    public static void main(String[] args) {
        int n = 5;
        System.out.println(countAndSay(n));
    }
}
Python
# Helper function to generate the next term 
# in the sequence from the previous one
def nextTerm(prev):
    curr = ""
    count = 1
    
    for i in range(1, len(prev)):
        
        # Keep Counting while same
        if prev[i] == prev[i - 1]:
            count += 1
            
        # If a different character found, append
        # the count of previous character along
        # with the character itself
        else:
            curr += str(count) + prev[i - 1]
            count = 1
    
    # Append the last character's count and the
    # last character
    curr += str(count) + prev[-1]
    
    return curr

# Recursive function to return the nth term
def countAndSay(n):
    
    # Base case
    if n == 1:
        return "1"
    
    # Recursively get the previous term
    prev = countAndSay(n - 1)
    
    # Get the n-th term using (n-1)th
    return nextTerm(prev)

# Driver code
if __name__ == "__main__":
    n = 5
    print(countAndSay(n))
C#
using System;
using System.Text;

// Helper function to generate the next term 
// in the sequence from the previous one
class GfG {
    public static string nextTerm(string prev) {
        StringBuilder curr = new StringBuilder();
        int count = 1;
        
        for (int i = 1; i < prev.Length; i++) {
            
            // Keep Counting while same
            if (prev[i] == prev[i - 1]) {
                count++;
                
            // If a different character found, append
            // the count of previous character along
            // with the character itself
            } else {
                curr.Append(count).Append(prev[i - 1]);
                count = 1;
            }
        }
        
        // Append the last character's count and the
        // last character
        curr.Append(count).Append(prev[prev.Length - 1]);
        
        return curr.ToString();
    }
    
    // Recursive function to return the nth term
    public static string countAndSay(int n) {
        
        // Base case
        if (n == 1)
            return "1";
        
        // Recursively get the previous term
        string prev = countAndSay(n - 1);
        
        // Get the n-th term using (n-1)th
        return nextTerm(prev);
    }
    
    // Driver code
    public static void Main(string[] args) {
        int n = 5;
        Console.WriteLine(countAndSay(n));
    }
}
JavaScript
// Helper function to generate the next term 
// in the sequence from the previous one
function nextTerm(prev) {
    let curr = "";
    let count = 1;
    
    for (let i = 1; i < prev.length; i++) {
        
        // Keep Counting while same
        if (prev[i] === prev[i - 1]) {
            count++;
        } else {
            
            // If a different character found, append
            // the count of previous character along
            // with the character itself
            curr += count.toString() + prev[i - 1];
            count = 1;
        }
    }
    
    // Append the last character's count and the
    // last character
    curr += count.toString() + prev[prev.length - 1];
    
    return curr;
}

// Recursive function to return the nth term
function countAndSay(n) {
    
    // Base case
    if (n === 1) {
        return "1";
    }
    
    // Recursively get the previous term
    const prev = countAndSay(n - 1);
    
    // Get the n-th term using (n-1)th
    return nextTerm(prev);
}

// Driver code
const n = 5;
console.log(countAndSay(n));

Output
111221

Why is the time complexity exponential?

The next term can be at-most double the size of previous term. We get double size when all characters are different. So an upper bound on the time complexity would be O(2n). We need this long string also for output and O(n) space for recursion. That is why the space is O(2n + n).

Iterative Solution - O(2^n) Time and O(2^n) Space

Instead of recursively generating the previous term, we build all terms one by one from first term which is "1" to the nth term. To generate the next term, we use the same idea as used in the above recursive solution.

C++
#include <bits/stdc++.h>
using namespace std;

// Iterative function to return the nth term
string countAndSay(int n) {
    if (n == 1)
        return "1";

    string curr = "1";

    // Start from the second term, build every term
    // terms using the previous term
    for (int i = 2; i <= n; i++) {
        string next = "";
       
        int cnt = 1;

        for (int j = 1; j < curr.length(); j++) {
            
            // If same as previous, then increment
            // count
            if (curr[j] == curr[j - 1]) {
                cnt++;

            // If different process the previous 
            // character and its count and reset
            // count for the current character
            } else {
                next += to_string(cnt) + curr[j - 1];
                cnt = 1;
            }
        }

        next += to_string(cnt) + curr.back(); 
        curr = next;
    }

    return curr;
}

// Driver code
int main() {
    int n = 5;
    cout << countAndSay(n) << endl;
    return 0;
}
Java
// Iterative function to return the nth term
class GfG {
    
    public static String countAndSay(int n) {
        
        if (n == 1) return "1";

        String curr = "1";

        // Start from the second term, build every term
        // terms using the previous term
        for (int i = 2; i <= n; i++) {
            StringBuilder next = new StringBuilder();
            int cnt = 1;

            for (int j = 1; j < curr.length(); j++) {
                
                // If same as previous, then increment
                // count
                if (curr.charAt(j) == curr.charAt(j - 1)) {
                    cnt++;
                    
                // If different process the previous 
                // character and its count and reset
                // count for the current character
                } else {
                    next.append(cnt).append(curr.charAt(j - 1));
                    cnt = 1;
                }
            }

            next.append(cnt).append(curr.charAt(curr.length() - 1));
            curr = next.toString();
        }

        return curr;
    }

    // Driver code
    public static void main(String[] args) {
        int n = 5;
        System.out.println(countAndSay(n));
    }
}
Python
# Iterative function to return the nth term
def countAndSay(n):
    if n == 1:
        return "1"

    curr = "1"

    # Start from the second term, build every term
    # terms using the previous term
    for i in range(2, n + 1):
        nextStr = ""
        cnt = 1

        for j in range(1, len(curr)):
            
            # If same as previous, then increment
            # count
            if curr[j] == curr[j - 1]:
                cnt += 1
                
            # If different process the previous 
            # character and its count and reset
            # count for the current character
            else:
                nextStr += str(cnt) + curr[j - 1]
                cnt = 1

        nextStr += str(cnt) + curr[-1]
        curr = nextStr

    return curr

# Driver code
if __name__ == "__main__":
    n = 5
    print(countAndSay(n))
C#
// Iterative function to return the nth term
using System;

class GfG{
    
    public static string countAndSay(int n) {
        if (n == 1) return "1";

        string curr = "1";

        // Start from the second term, build every term
        // terms using the previous term
        for (int i = 2; i <= n; i++) {
            string next = "";
            int cnt = 1;

            for (int j = 1; j < curr.Length; j++) {
                
                // If same as previous, then increment
                // count
                if (curr[j] == curr[j - 1]) {
                    cnt++;
                    
                // If different process the previous 
                // character and its count and reset
                // count for the current character
                } else {
                    next += cnt.ToString() + curr[j - 1];
                    cnt = 1;
                }
            }

            next += cnt.ToString() + curr[curr.Length - 1];
            curr = next;
        }

        return curr;
    }

    // Driver code
    public static void Main() {
        int n = 5;
        Console.WriteLine(countAndSay(n));
    }
}
JavaScript
// Iterative function to return the nth term
function countAndSay(n) {
    if (n === 1) return "1";

    let curr = "1";

    // Start from the second term, build every term
    // terms using the previous term
    for (let i = 2; i <= n; i++) {
        let next = "";
        let cnt = 1;

        for (let j = 1; j < curr.length; j++) {
            
            // If same as previous, then increment
            // count
            if (curr[j] === curr[j - 1]) {
                cnt++;
                
            // If different process the previous 
            // character and its count and reset
            // count for the current character
            } else {
                next += cnt.toString() + curr[j - 1];
                cnt = 1;
            }
        }

        next += cnt.toString() + curr[curr.length - 1];
        curr = next;
    }

    return curr;
}

// Driver code
const n = 5;
console.log(countAndSay(n));

Output
111221

Next Article

Similar Reads