Problem of The Day: The k-th Lexicographical String of All Happy Strings of Length n
Problem Statement

Intuition
The problem requires generating a lexicographically sorted list of “happy strings” of length n using the characters ‘a’, ‘b’, and ‘c’. A “happy string” is defined as a string where no two consecutive characters are the same. Given an integer k, we return the k-th lexicographically smallest happy string.
The first intuition is to use backtracking to generate all possible happy strings and store them in a min-heap to track the k-th smallest string efficiently.
Approach
- Use a recursive function generate_happy_stringto generate all possible happy strings of lengthn.
- Maintain a min-heap (min_heap) to store the happy strings in lexicographic order.
- At each step, append one of the characters (‘a’, ‘b’, or ‘c’) to the current string, ensuring that the last character is not repeated.
- Once the length of the string reaches n, add it to the heap.
- Return the k-th smallest string from the heap, or an empty string ifkis out of bounds.
Complexity
- 
    Time Complexity: - Since each position in the string can be filled with at most 2 choices (excluding the previous character), the total number of happy strings is at most O(2^n). Since heap operations takeO(log k), the overall complexity is approximatelyO(2^n log k).
 
- Since each position in the string can be filled with at most 2 choices (excluding the previous character), the total number of happy strings is at most 
- 
    Space Complexity: - The recursion depth is O(n), and the heap can store up toO(2^n)elements in the worst case. Thus, the space complexity isO(2^n).
 
- The recursion depth is 
Code
import heapq
class Solution:
    def getHappyString(self, n: int, k: int) -> str:
        min_heap = []
        def generate_happy_string(letters, curr, start):
            if len(curr) == n:
                heapq.heappush(min_heap, "".join(curr))
                return
            for i in range(3):
                if curr and curr[-1] == letters[i]:
                    continue
                generate_happy_string(letters, curr + [letters[i]], i)
        generate_happy_string("abc", [], 0)
        return min_heap[k - 1] if 0 <= k - 1 < len(min_heap) else ""
Editorial
Approach 1: Backtracking
class Solution:
    def getHappyString(self, n: int, k: int) -> str:
        current_string = ""
        happy_strings = []
        # Generate all happy strings of length n
        self.generate_happy_strings(n, current_string, happy_strings)
        # Check if there are at least k happy strings
        if len(happy_strings) < k:
            return ""
        # Sort the happy strings in lexicographical order
        happy_strings.sort()
        return happy_strings[k - 1]
    def generate_happy_strings(
        self, n: int, current_string: str, happy_strings: list
    ):
        # If the current string has reached the desired length, add it to the list
        if len(current_string) == n:
            happy_strings.append(current_string)
            return
        # Try adding each character ('a', 'b', 'c') to the current string
        for current_char in ["a", "b", "c"]:
            # Skip if the current character is the same as the last character
            if len(current_string) > 0 and current_string[-1] == current_char:
                continue
            # Recursively generate the next character
            self.generate_happy_strings(
                n, current_string + current_char, happy_strings
            )
- time: O(n * 2^n)
- space: O(2^n)
Approach 2: Optimized Recursion
class Solution:
    def getHappyString(self, n: int, k: int) -> str:
        self.current_string = ""
        self.result = ""
        self.index_in_sorted_list = 0
        # Generate happy strings and track the k-th string
        self.generate_happy_strings(n, k)
        return self.result
    def generate_happy_strings(self, n, k):
        # If the current string has reached the desired length
        if len(self.current_string) == n:
            # Increment the count of generated strings
            self.index_in_sorted_list += 1
            # If this is the k-th string, store it in the result
            if self.index_in_sorted_list == k:
                self.result = self.current_string
            return
        # Try adding each character ('a', 'b', 'c') to the current string
        for current_char in ["a", "b", "c"]:
            # Skip if the current character is the same as the last one
            if (
                len(self.current_string) > 0
                and self.current_string[-1] == current_char
            ):
                continue
            self.current_string += current_char
            # Recursively generate the next character
            self.generate_happy_strings(n, k)
            # If the result is found, stop further processing
            if self.result != "":
                return
            # Backtrack by removing the last character
            self.current_string = self.current_string[:-1]
Approach 3: Iterative Using a Stack
class Solution:
    def getHappyString(self, n: int, k: int) -> str:
        strings_stack = []
        index_in_sorted_list = 0
        strings_stack.append("")  # Start with an empty string
        while strings_stack:
            current_string = strings_stack.pop()
            # If we have built a string of length n, count it
            if len(current_string) == n:
                index_in_sorted_list += 1
                # If we reach the k-th happy string, return it
                if index_in_sorted_list == k:
                    return current_string
                continue
            # Expand the current string by adding 'a', 'b', or 'c'
            # Ensuring lexicographic order by pushing in reverse
            for current_char in reversed(["a", "b", "c"]):
                # Avoid consecutive identical characters
                if (
                    len(current_string) == 0
                    or current_string[-1] != current_char
                ):
                    strings_stack.append(current_string + current_char)
        return ""