给定一个只包含小写字母的有序数组letters 和一个目标字母 target,寻找有序数组里面比目标字母大的最小字母。
数组里字母的顺序是循环的。举个例子,如果目标字母target = ‘z’ 并且有序数组为 letters = [‘a’, ‘b’],则答案返回 ‘a’。
示例:
输入:
letters = [“c”, “f”, “j”]
target = “a”
输出: “c”
输入:
letters = [“c”, “f”, “j”]
target = “c”
输出: “f”
输入:
letters = [“c”, “f”, “j”]
target = “d”
输出: “f”
输入:
letters = [“c”, “f”, “j”]
target = “g”
输出: “j”
输入:
letters = [“c”, “f”, “j”]
target = “j”
输出: “c”
输入:
letters = [“c”, “f”, “j”]
target = “k”
输出: “c”
注:
- letters长度范围在[2, 10000]区间内。
- letters 仅由小写字母组成,最少包含两个不同的字母。
- 目标字母target 是一个小写字母。
代码实现
C++
一看到"已排序"就开心了。
因为有序所以我们通过二分查找算法来实现。
根据二分查找算法的原理,我们定义三个变量left,right和mid,分别初始化为0,数组长度,数组长度的一半;临界条件我们定为 left<right。
我们要找的是比target大一点的字母,所以当target大于等于数组中的当前元素时,说明我们要找的元素在当前元素的右边;否则就在当前元素的左边。
我们不断的缩小查找范围。当跳出循环时,会出现下面两种情况:
- 位于下标left处的元素大于targe,那么返回left处的元素。例如letters=[e,f,g], target = a;
- 位于下标left处的元素小于等于targe,那么返回left+1处的元素。例如letters=[e,f,g], target = e;
此外我们还要考虑一种特殊情况,即如果target大于等于letters中的最大元素,即最后一个元素,那么返回letters[0]。
所以最终的代码如下:
class Solution {
public:
char nextGreatestLetter(vector<char>& letters, char target) {
//判断traget是否大于letters中所有元素,如果是返回letters[0]
if(target > letters[letters.size()-1]){
return letters[0];
}
int left=0, right=letters.size(), middle=int(letters.size()/2.0);
for(; left<right; middle=int((left+right)/2.0)){
//判断此时数组的中间值是否大于目标值
if(target >= letters[middle]){
left = ++middle;
}
else{
right = --middle;
}
}
return letters[left] > target ? letters[left]:letters[left+1];
}
};
Python:
class Solution(object):
def nextGreatestLetter(self, letters, target):
"""
:type letters: List[str]
:type target: str
:rtype: str
"""
if target >= letters[-1]:
return letters[0]
left = 0
right = len(letters)
middle = 0
while left < right:
middle = (left + right)//2
if letters[middle] <= target:
left = middle+1
else:
right = middle-1
#return letters[left] if target>letters[left] else letters[left+1]
if target > letters[left]:
return letters[left]
else:
return letters[left+1]