You are given an array of characters letters
that is sorted in non-decreasing order, and a character target
. There are at least two different characters in letters
.
Return the smallest character in letters
that is lexicographically greater than target
. If such a character does not exist, return the first character in letters
.
Example 1:
Input: letters = ["c","f","j"], target = "a" Output: "c" Explanation: The smallest character that is lexicographically greater than 'a' in letters is 'c'.
Example 2:
Input: letters = ["c","f","j"], target = "c" Output: "f" Explanation: The smallest character that is lexicographically greater than 'c' in letters is 'f'.
Example 3:
Input: letters = ["x","x","y","y"], target = "z" Output: "x" Explanation: There are no characters in letters that is lexicographically greater than 'z' so we return letters[0].
Constraints:
2 <= letters.length <= 104
letters[i]
is a lowercase English letter.letters
is sorted in non-decreasing order.letters
contains at least two different characters.target
is a lowercase English letter.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:
The problem requires us to find the smallest letter in a list that is bigger than a specific target letter. A brute-force approach simply checks each letter in the list one by one against the target letter until it finds the right one.
Here's how the algorithm would work step-by-step:
def find_smallest_letter_greater_than_target_brute_force(letters, target):
# Iterate through each letter in the list.
for letter in letters:
# Check if the current letter is greater than the target.
if letter > target:
return letter
# If we reach here, no letter was greater. Reset and start from beginning.
return letters[0]
The fastest way to find the right letter is to use a method similar to looking up a word in a dictionary. We can quickly narrow down the possibilities by repeatedly dividing the search area in half. This avoids checking each letter individually.
Here's how the algorithm would work step-by-step:
def find_smallest_letter_greater_than_target(letters, target):
left_index = 0
right_index = len(letters) - 1
while left_index <= right_index:
middle_index = (left_index + right_index) // 2
middle_letter = letters[middle_index]
# Narrow search to the left half if middle letter is greater
if middle_letter > target:
right_index = middle_index - 1
# Otherwise, narrow search to the right half
else:
left_index = middle_index + 1
# Wraparound: target is greater than or equal to all letters.
if left_index == len(letters):
return letters[0]
# Return the smallest letter greater than target
else:
return letters[left_index]
Case | How to Handle |
---|---|
Empty letters array | Return the default value or throw an exception as there is no smallest greater letter. |
Target is greater than or equal to all letters in letters array | Return the first letter in the array, as it wraps around. |
Letters array contains only one letter | Return the single letter if it is greater than target, or return the same letter if it is not. |
Letters array contains duplicate letters | The algorithm should still return the smallest greater letter correctly, ignoring duplicate positions. |
Target is less than all letters in letters array | Return the first element of the array since it is the smallest greater letter. |
Letters array contains all identical letters equal to the target | Return the first letter in the array as that will be smallest greater letter due to wraparound. |
Letters array is very large (potential memory issues) | Binary search should be efficient enough to handle very large array sizes without memory issues. |
Target is the largest possible character value | The first element should be returned due to the wraparound behavior. |