
Problem Statement
In the given problem, you are provided with a sorted array of characters named letters and a character called target. The array is sorted in non-decreasing order, which means some characters can repeat but the sequence will not have any characters in a descending order. Your task is to find the smallest character in this array that is lexicographically greater than the target. If such a character does not exist in the array, which means all characters in the array are either equal or less than the target, you should return the first character of the array. The sorting order of characters and the defined target ensure intriguing test scenarios for boundary checks, especially with repeating characters and those at the edge of the alphabet.
Examples
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 <= 104letters[i]is a lowercase English letter.lettersis sorted in non-decreasing order.letterscontains at least two different characters.targetis a lowercase English letter.
Approach and Intuition
Based on the examples provided, the solution approach can be broadly described as:
Check each character in the
lettersarray:- If a character is found that is greater than the
target, return this character immediately since the array is sorted and this will be the smallest character that fulfills the condition.
- If a character is found that is greater than the
If the traversal completes without finding any character greater than the
target:- Return the first character of the array. This handles cases where the
targetcharacter is greater than or equal to any character in thelettersarray.
- Return the first character of the array. This handles cases where the
Key Points to Consider:
Sorted Input: Since
lettersis sorted in non-decreasing order, as soon as you find a letter greater than thetarget, you can immediately return it. This takes advantage of the sorted nature of the array.Edge Cases:
- If
targetis greater than the last character inletters, the first character oflettersis returned, as seen in the examples whentargetwas 'z'. - The solution also elegantly handles cases where the
targetmight exactly match one of the characters inletters. Since we are looking for a character strictly greater, we would return the next character in the sequence.
- If
Linear Search Efficiency: Because the array is traversed sequentially to find the first character greater than
target, the worst-case time complexity is O(n). However, sincelettersare sorted, implementing a binary search could optimize it to O(log n).
This approach leverages both the properties of the sorted array and the specific requirements of finding a character just greater than a given target, ensuring that the solution is both intuitive and efficient within the outlined constraints.
Solutions
- C++
- Java
- Python
class Solution {
public:
char findNextChar(vector<char>& letters, char target) {
int start = 0, end = letters.size() - 1, middle;
while (start <= end) {
middle = (start + end) / 2;
if (letters[middle] <= target) {
start = middle + 1;
} else {
end = middle - 1;
}
}
return start == letters.size() ? letters[0] : letters[start];
}
};
The provided C++ solution addresses the problem of finding the smallest letter greater than a given target from a sorted list of letters. The approach effectively utilizes a binary search method to optimize the search process. Here's an outline of how the solution operates:
- Define a class
Solutionwith a public member functionfindNextChar, which takes a vector of characterslettersand a charactertargetas parameters. - Initialize two integer variables
startandendto represent the beginning and the end of the search range within the list. - Commence a while loop that continues as long as
startis less than or equal toend. Each iteration adjusts thestartandendbased on comparisons of the middle character in the current search range with thetarget.- Calculate the middle position of the current range.
- If the character at the middle position is less than or equal to the target, move the start point up (to
middle + 1), discarding the first half of the current search range as all these characters are less than or equal to the target. - Otherwise, adjust the end point down (to
middle - 1), keeping possible candidates in the range.
- After exiting the loop, check if the start index has exceeded the size of the list, which means the target character is greater than any character in the list. In this situation, return the first character from the list, effectively implementing a wrap-around as the list is sorted.
- If not, return the character found at the
startindex in the list as it will be the smallest character greater than the target.
This solution ensures a time complexity of O(log n), due to the binary search approach, making it efficient for large datasets.
class Solution {
public char findNextChar(char[] sequence, char reference) {
int start = 0, end = sequence.length - 1, pivot;
while (start <= end) {
pivot = (start + end) / 2;
if (sequence[pivot] <= reference) {
start = pivot + 1;
} else {
end = pivot - 1;
}
}
return start == sequence.length ? sequence[0] : sequence[start];
}
}
The Java solution presented efficiently finds the smallest character in a sorted array greater than a given target character utilizing binary search. Follow these steps to understand the underlying logic and execution flow of the method findNextChar:
Initialize Pointers: Two pointers,
startandend, are initialized to the beginning and end of the array respectively.Binary Search Process: Use a binary search loop wherein:
- Calculate the middle index
pivot. - If the element at
pivotis less than or equal to the reference character, move thestartindex topivot + 1. - If the element is greater, adjust the
endindex topivot - 1.
- Calculate the middle index
Determine Result: After exiting the loop, check if
starthas moved beyond the last index of the array. If so, the smallest letter is wrapped around to the first element of the array (sequence[0]). Otherwise, return the element at thestartindex.
This method ensures an optimal O(log n) time complexity, making it efficient even for large datasets. It handles scenarios where no direct match is found, and even when all characters in the array are less than or equal to the target character.
class Solution:
def next_larger_character(self, chars: List[str], ref_char: str) -> str:
low = 0
high = len(chars) - 1
while low <= high:
middle = (low + high) // 2
if chars[middle] <= ref_char:
low = middle + 1
else:
high = middle - 1
if low == len(chars):
return chars[0]
else:
return chars[low]
This solution uses a binary search algorithm to efficiently solve the problem of finding the smallest letter greater than a given target within a sorted list of characters. The function next_larger_character takes two parameters: a list of characters chars and a reference character ref_char.
Follow these steps to understand the implementation within a Python environment:
Initialize two pointers,
lowandhigh, which represent the starting and ending bounds of your search area within the list of characters.lowstarts at 0 andhighstarts at the last valid index,len(chars) - 1.Implement a binary search loop:
- Calculate the middle index by averaging
lowandhigh. - Compare the middle character
chars[middle]with the reference characterref_char:- If
chars[middle]is less than or equal toref_char, it means the desired letter must be further in the list. Therefore, setlowtomiddle + 1to search the upper half. - Otherwise, the smallest larger character might be at
middleor to its left, so sethightomiddle - 1to explore the lower half.
- If
- Calculate the middle index by averaging
After the loop, check if
lowequals the length of the list:- If true, this indicates that all characters in the list are less than or equal to the
ref_char. Therefore, return the first character in the list as it is circularly greater. - Otherwise, return the character at the
lowindex, which is the smallest character greater thanref_char.
- If true, this indicates that all characters in the list are less than or equal to the
This approach efficiently pinpoints the desired character by reducing the search space in half with each iteration, allowing it to run in logarithmic time complexity relative to the size of the input list. Moreover, by leveraging the sorted nature of the list, this solution guarantees that the first element found greater than ref_char after all iterations is the smallest such element.