38. Count and Say

Difficulty: Medium

Topics: String

The count-and-say sequence is a sequence of digit strings defined by the recursive formula:

  • countAndSay(1) = "1"
  • countAndSay(n) is the run-length encoding of countAndSay(n - 1).

Run-length encoding (RLE) is a string compression method that works by replacing consecutive identical characters (repeated 2 or more times) with the concatenation of the character and the number marking the count of the characters (length of the run). For example, to compress the string "3322251" we replace "33" with "23", replace "222" with "32", replace "5" with "15" and replace "1" with "11". Thus the compressed string becomes "23321511".

Given a positive integer n, return the nth element of the count-and-say sequence.

Example 1:

  • Input: n = 4
  • Output: "1211"
  • Explanation:
countAndSay(1) = "1"
countAndSay(2) = RLE of "1" = "11"
countAndSay(3) = RLE of "11" = "21"
countAndSay(4) = RLE of "21" = "1211"

Example 2:

  • Input: n = 1
  • Output: "1"
  • Explanation: This is the base case.

Constraints:

  • 1 <= n <= 30

Hint:

  1. Create a helper function that maps an integer to pairs of its digits and their frequencies. For example, if you call this function with "223314444411", then it maps it to an array of pairs [[2,2], [3,2], [1,1], [4,5], [1, 2]].
  2. Create another helper function that takes the array of pairs and creates a new integer. For example, if you call this function with [[2,2], [3,2], [1,1], [4,5], [1, 2]], it should create "22"+"23"+"11"+"54"+"21" = "2223115421".
  3. Now, with the two helper functions, you can start with "1" and call the two functions alternatively n-1 times. The answer is the last integer you will obtain.

Solution:

We need to generate 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 using run-length encoding.

Approach

  1. Initialization: Start with the base case where the first term (n=1) is "1".
  2. Iterative Generation: For each subsequent term from 2 to n, generate the term by processing the previous term:
    • Traverse the previous term and group consecutive identical digits.
    • For each group, append the count followed by the digit to form the new term.
  3. Term Construction: Construct each new term by iterating through the previous term, tracking the count of consecutive digits, and appending the count and digit to the result string once a different digit is encountered or the end of the string is reached.

Let's implement this solution in PHP: 38. Count and Say

/**
 * @param Integer $n
 * @return String
 */
function countAndSay($n) {
    ...
    ...
    ...
    /**
     * go to ./solution.php
     */
}

// Test
echo countAndSay(4);  // Output: 1211
echo countAndSay(1);  // Output: 1
?>

Explanation:

  1. Base Case Handling: If n is 1, directly return "1".
  2. Loop Through Terms: For each term from 2 to n, generate the term by processing the previous term.
  3. Character Grouping: Track consecutive characters in the current term. When a different character is encountered, append the count and the character to the result string.
  4. Final Group Handling: After the loop, append the count and character for the last group to ensure all parts of the string are processed.

This approach efficiently builds each term iteratively, ensuring that each term is generated by describing the previous term using run-length encoding. The time complexity is O(n * m), where m is the maximum length of any term up to n, which is manageable given the constraints (n ≤ 30).

Contact Links

If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

If you want more helpful content like this, feel free to follow me: