Find Smallest Letter Greater Than Target
Find Smallest Letter Greater Than Target:
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 <= 10^4.letters[i]is a lowercase English letter.lettersis sorted in non-decreasing order.letterscontains at least two different characters.targetis a lowercase English letter.
Try this Problem on your own or check similar problems:
Solution:
- Java
- JavaScript
- Python
- C++
public char nextGreatestLetter(char[] letters, char target) {
int low = 0, n = letters.length, high = n;
while(low < high){
int mid = low + (high - low) / 2;
if(letters[mid] > target){
high = mid;
}else{
low = mid + 1;
}
}
return letters[low % n];
}
/**
* @param {character[]} letters
* @param {character} target
* @return {character}
*/
var nextGreatestLetter = function (letters, target) {
let low = 0;
let high = letters.length;
while (low < high) {
let mid = low + Math.floor((high - low) / 2);
if (letters[mid] > target) {
high = mid;
} else {
low = mid + 1;
}
}
return letters[low % letters.length];
};
class Solution:
def nextGreatestLetter(self, letters: List[str], target: str) -> str:
low = 0
high = len(letters)
while low < high:
mid = low + (high - low) // 2
if letters[mid] > target:
high = mid
else:
low = mid + 1
return letters[low % len(letters)]
class Solution {
public:
char nextGreatestLetter(vector<char>& letters, char target) {
int low = 0, high = letters.size();
while (low < high) {
int mid = low + (high - low) / 2;
if (letters[mid] > target) {
high = mid;
} else {
low = mid + 1;
}
}
return letters[low % letters.size()];
}
};
Time/Space Complexity:
- Time Complexity: O(log n)
- Space Complexity: O(1)
Explanation:
Modification on Binary Search with few tricks:
letters[low % n]at the end of looplowmight have converged to theendof array, so we take the modulo to return the first element as per problem statement.- We keep the
low < highloop invariant, so at any iteration we have either foundmidwhich is larger thantargetand then thehighis pointing to the same element asmid(our current best solution) or it's pointing to the end of array (out of boundary) no mid elements are found that are larger thantarget. - Why do we set
high = midand nothigh = mid + 1? From the previous point, high might be pointing to valid element (element larger than target) so we cannot remove it from the search, we can however eliminate all the other elements coming aftermidsince mid is the smallest element larger thantargetin the second half. - At the end of loop
lowhas converged tohighand it's either pointing to smallest elements larger thantargetor out of array.