A happy string is a string that:
['a', 'b', 'c'].s[i] != s[i + 1] for all values of i from 1 to s.length - 1 (string is 1-indexed).For example, strings "abc", "ac", "b" and "abcbabcbcb" are all happy strings and strings "aa", "baa" and "ababbc" are not happy strings.
Given two integers n and k, consider a list of all happy strings of length n sorted in lexicographical order.
Return the kth string of this list or return an empty string if there are less than k happy strings of length n.
Example 1:
Input: n = 1, k = 3 Output: "c" Explanation: The list ["a", "b", "c"] contains all happy strings of length 1. The third string is "c".
Example 2:
Input: n = 1, k = 4 Output: "" Explanation: There are only 3 happy strings of length 1.
Example 3:
Input: n = 3, k = 9 Output: "cab" Explanation: There are 12 different happy string of length 3 ["aba", "abc", "aca", "acb", "bab", "bac", "bca", "bcb", "cab", "cac", "cba", "cbc"]. You will find the 9th string = "cab"
Constraints:
1 <= n <= 101 <= k <= 100When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach involves generating all possible strings that meet the 'happy string' criteria (no consecutive characters are the same) and are of the desired length. Then, we order these strings lexicographically (like in a dictionary) and select the k-th string. This is like trying every possible combination until we find the one we're looking for.
Here's how the algorithm would work step-by-step:
def find_kth_lexicographical_happy_string(string_length, kth_string):
happy_strings = []
def generate_strings(current_string, length):
if length == 0:
# Base case: string of desired length reached
is_happy = True
for i in range(len(current_string) - 1):
if current_string[i] == current_string[i + 1]:
is_happy = False
break
if is_happy:
happy_strings.append(current_string)
return
generate_strings(current_string + 'a', length - 1)
generate_strings(current_string + 'b', length - 1)
generate_strings(current_string + 'c', length - 1)
generate_strings('', string_length)
# Filter out non-happy strings
filtered_happy_strings = []
for potential_happy_string in happy_strings:
is_happy = True
for i in range(len(potential_happy_string) - 1):
if potential_happy_string[i] == potential_happy_string[i + 1]:
is_happy = False
break
if is_happy:
filtered_happy_strings.append(potential_happy_string)
# Sort the happy strings lexicographically.
filtered_happy_strings.sort()
# Return the kth happy string, if it exists.
if kth_string <= len(filtered_happy_strings):
return filtered_happy_strings[kth_string - 1]
else:
return ""The goal is to find a specific 'happy' string based on its position in a sorted list of all such strings. Instead of creating all happy strings and then sorting, we directly construct the k-th string by making informed choices at each position, drastically reducing the computation.
Here's how the algorithm would work step-by-step:
def get_happy_string(string_length, kth_string):
number_of_happy_strings = 3 * (2**(string_length - 1))
if kth_string > number_of_happy_strings:
return ""
result = ""
available_characters = ['a', 'b', 'c']
# Determine the first character based on k and total strings
base_count = (2**(string_length - 1))
if kth_string <= base_count:
result += 'a'
elif kth_string <= 2 * base_count:
result += 'b'
kth_string -= base_count
else:
result += 'c'
kth_string -= 2 * base_count
for _ in range(1, string_length):
# Choose the next character, ensuring it's different
next_available_chars = [char for char in available_characters if char != result[-1]]
base_count //= 2
# Reduce the problem size
if kth_string <= base_count:
result += next_available_chars[0]
else:
result += next_available_chars[1]
kth_string -= base_count
return result| Case | How to Handle |
|---|---|
| n is zero | Return an empty string, as there are no happy strings of length zero. |
| k is zero or negative | Return an empty string or throw an IllegalArgumentException as the kth element does not exist for non-positive k. |
| k is larger than the total number of happy strings of length n | Return an empty string or throw an IllegalArgumentException if k is too large; the maximum number of happy strings is 3 * 2^(n-1). |
| n is one | Handle this base case separately, returning 'a', 'b', or 'c' based on the value of k. |
| n is relatively large (e.g., 20) | Ensure that the algorithm used scales efficiently to avoid timeouts, favoring iterative approaches over naive recursion. |
| Integer overflow during calculation of total number of happy strings or index calculations | Use long data type to store and calculate the number of happy strings or intermediate indices to prevent overflow, or return an empty string if overflow is still possible. |
| n is negative | Throw an IllegalArgumentException if n is negative as string length cannot be negative. |
| Extreme values of n leading to memory exhaustion | Limit maximum n value to prevent excessive memory allocation and potential out of memory errors, or return an empty string. |