
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 <= 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.
Approach and Intuition
Based on the examples provided, the solution approach can be broadly described as:
Check each character in the
letters
array:- 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
target
character is greater than or equal to any character in theletters
array.
- Return the first character of the array. This handles cases where the
Key Points to Consider:
Sorted Input: Since
letters
is 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
target
is greater than the last character inletters
, the first character ofletters
is returned, as seen in the examples whentarget
was 'z'. - The solution also elegantly handles cases where the
target
might 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, sinceletters
are 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
Solution
with a public member functionfindNextChar
, which takes a vector of charactersletters
and a charactertarget
as parameters. - Initialize two integer variables
start
andend
to represent the beginning and the end of the search range within the list. - Commence a while loop that continues as long as
start
is less than or equal toend
. Each iteration adjusts thestart
andend
based 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
start
index 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,
start
andend
, 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
pivot
is less than or equal to the reference character, move thestart
index topivot + 1
. - If the element is greater, adjust the
end
index topivot - 1
.
- Calculate the middle index
Determine Result: After exiting the loop, check if
start
has 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 thestart
index.
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,
low
andhigh
, which represent the starting and ending bounds of your search area within the list of characters.low
starts at 0 andhigh
starts at the last valid index,len(chars) - 1
.Implement a binary search loop:
- Calculate the middle index by averaging
low
andhigh
. - 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, setlow
tomiddle + 1
to search the upper half. - Otherwise, the smallest larger character might be at
middle
or to its left, so sethigh
tomiddle - 1
to explore the lower half.
- If
- Calculate the middle index by averaging
After the loop, check if
low
equals 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
low
index, 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.
No comments yet.