1. 程式人生 > >[LeetCode] Find Smallest Letter Greater Than Target 找比目標值大的最小字母

[LeetCode] Find Smallest Letter Greater Than Target 找比目標值大的最小字母

Given a list of sorted characters letters containing only lowercase letters, and given a target letter target, find the smallest element in the list that is larger than the given target.

Letters also wrap around. For example, if the target is target = 'z' and letters = ['a', 'b'], the answer is 'a'

.

Examples:

Input:
letters = ["c", "f", "j"]
target = "a"
Output: "c"

Input:
letters = ["c", "f", "j"]
target = "c"
Output: "f"

Input:
letters = ["c", "f", "j"]
target = "d"
Output: "f"

Input:
letters = ["c", "f", "j"]
target = "g"
Output: "j"

Input:
letters = ["c", "f", "j"]
target = "j"
Output: "c"

Input:
letters = ["c", "f", "j"]
target = "k"
Output: "c"

Note:

  1. letters has a length in range [2, 10000].
  2. letters consists of lowercase letters, and contains at least 2 unique letters.
  3. target is a lowercase letter.

這道題給了我們一堆有序的字母,然後又給了我們一個target字母,讓我們求字母陣列中第一個大於target的字母,陣列是迴圈的,如果沒有,那就返回第一個字母。像這種在有序陣列中找數字,二分法簡直不要太適合啊。題目中說了陣列至少有兩個元素,那麼我們首先用陣列的尾元素來跟target比較,如果target大於等於尾元素的話,直接返回陣列的首元素即可。否則就利用二分法來做,這裡是查詢第一個大於目標值的陣列,博主之前做過二分法的總結,參見這個帖子

LeetCode Binary Search Summary 二分搜尋法小結,參見程式碼如下:

解法一:

class Solution {
public:
    char nextGreatestLetter(vector<char>& letters, char target) {
        if (target >= letters.back()) return letters[0];
        int n = letters.size(), left = 0, right = n;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (letters[mid] <= target) left = mid + 1;
            else right = mid;
        }
        return letters[right];
    }
};

我們也可以用STL自帶的upper_bound函式來做,這個就是找第一個大於目標值的數字,如果返回end(),說明沒找到,返回首元素即可,參見程式碼如下:

解法二:

class Solution {
public:
    char nextGreatestLetter(vector<char>& letters, char target) {
        auto it = upper_bound(letters.begin(), letters.end(), target);
        return it == letters.end() ? *letters.begin() : *it;
    }
};