Given a string s
, return the last substring of s
in lexicographical order.
Example 1:
Input: s = "abab" Output: "bab" Explanation: The substrings are ["a", "ab", "aba", "abab", "b", "ba", "bab"]. The lexicographically maximum substring is "bab".
Example 2:
Input: s = "leetcode" Output: "tcode"
Constraints:
1 <= s.length <= 4 * 105
s
contains only lowercase English letters.When 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:
We want to find the very last substring if we were to alphabetize all the substrings of a given string. The brute force way is to simply generate every possible substring and then compare them all to find the largest.
Here's how the algorithm would work step-by-step:
def last_substring_brute_force(input_string):
largest_substring = ""
# Iterate through all possible substring lengths
for substring_length in range(1, len(input_string) + 1):
# Iterate through all possible starting positions for each length
for start_index in range(len(input_string) - substring_length + 1):
current_substring = input_string[start_index:start_index + substring_length]
# Compare the current substring with the largest found so far
if current_substring > largest_substring:
# Update if lexicographically larger
largest_substring = current_substring
return largest_substring
The goal is to find the alphabetically largest chunk of text within the input text. The most efficient approach avoids comparing every possible chunk by cleverly tracking potential candidates and comparing only when necessary, focusing on the defining characteristics of alphabetical order.
Here's how the algorithm would work step-by-step:
def last_substring(input_string):
largest_substring_index = len(input_string) - 1
for current_index in range(len(input_string) - 1):
# Compare current substring with the largest substring.
if input_string[current_index:] > input_string[largest_substring_index:]:
largest_substring_index = current_index
# Prioritize earlier occurence if substrings are equal
elif input_string[current_index:] == input_string[largest_substring_index:]:
continue
# Returning the actual substring is required
return input_string[largest_substring_index:]
Case | How to Handle |
---|---|
Empty string s | Return an empty string since there are no substrings. |
String s with length 1 | Return the string itself as it is the only substring and hence the largest. |
String s with all identical characters (e.g., 'aaaa') | Return the entire string as it is the lexicographically largest substring. |
Maximum length string (performance implications) | Ensure the chosen algorithm (e.g., optimized two-pointer approach) has acceptable time complexity, preferably O(n) or close to it, to avoid timeouts. |
String with characters near the end of the ASCII table (e.g., 'xyz') | The algorithm should correctly handle characters with high ASCII values. |
String with repeating patterns (e.g., 'ababab') | The algorithm should correctly identify the last substring even with repeating patterns. |
String with a single extremely large character at the end (e.g., 'abcxyz') | The algorithm correctly identifies the 'xyz' as the greatest substring |
String containing non-ASCII characters (extended ASCII or Unicode) | Ensure the comparison logic correctly handles non-ASCII characters based on their Unicode code points. |