Find Smallest Letter Greater Than Target

Updated on 28 May, 2025
Find Smallest Letter Greater Than Target header image

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:

  1. 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.
  2. 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 the letters array.

Key Points to Consider:

  • Sorted Input: Since letters is sorted in non-decreasing order, as soon as you find a letter greater than the target, 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 in letters, the first character of letters is returned, as seen in the examples when target was 'z'.
    • The solution also elegantly handles cases where the target might exactly match one of the characters in letters. Since we are looking for a character strictly greater, we would return the next character in the sequence.
  • 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, since letters 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
cpp
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 function findNextChar, which takes a vector of characters letters and a character target as parameters.
  • Initialize two integer variables start and end 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 to end. Each iteration adjusts the start and end based on comparisons of the middle character in the current search range with the target.
    • 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.

java
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:

  1. Initialize Pointers: Two pointers, start and end, are initialized to the beginning and end of the array respectively.

  2. 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 the start index to pivot + 1.
    • If the element is greater, adjust the end index to pivot - 1.
  3. 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 the start 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.

python
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:

  1. Initialize two pointers, low and high, which represent the starting and ending bounds of your search area within the list of characters. low starts at 0 and high starts at the last valid index, len(chars) - 1.

  2. Implement a binary search loop:

    • Calculate the middle index by averaging low and high.
    • Compare the middle character chars[middle] with the reference character ref_char:
      • If chars[middle] is less than or equal to ref_char, it means the desired letter must be further in the list. Therefore, set low to middle + 1 to search the upper half.
      • Otherwise, the smallest larger character might be at middle or to its left, so set high to middle - 1 to explore the lower half.
  3. 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 than ref_char.

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.

Comments

No comments yet.