注意!!!朋友面试遇到的某公司面试原题
给你一个字符数组 letters
,该数组按非递减顺序排序,以及一个字符 target
。letters
里至少有两个不同的字符。
返回 letters
中大于 target
的最小的字符。如果不存在这样的字符,则返回 letters
的第一个字符。
示例 1:
输入: letters = ["c", "f", "j"],target = "a" 输出: "c" 解释:letters 中字典上比 'a' 大的最小字符是 'c'。
示例 2:
输入: letters = ["c","f","j"], target = "c" 输出: "f" 解释:letters 中字典顺序上大于 'c' 的最小字符是 'f'。
示例 3:
输入: letters = ["x","x","y","y"], target = "z" 输出: "x" 解释:letters 中没有一个字符在字典上大于 'z',所以我们返回 letters[0]。
提示:
2 <= letters.length <= 104
letters[i]
是一个小写字母letters
按非递减顺序排序letters
最少包含两个不同的字母target
是一个小写字母
1、遍历
由题意可得数组已经升序排列,而在大多数语言中,字符类型是可以直接用比较符号的,所以遍历的思路就是,一旦遇到比target大的字符,那直接返回即可,后续遍历就没有意义了。由于target可能比数组的最大值大,一旦遍历找不到比target大的,直接返回数组第一个元组即可(数组最小值)。
时间复杂度:O(N),N为数组长度,一次遍历所花时间
空间复杂度:O(1)
python:
class Solution:
def nextGreatestLetter(self, letters: List[str], target: str) -> str:
for i in letters:
if i > target:
return i
return letters[0]
java:
class Solution {
public char nextGreatestLetter(char[] letters, char target) {
for (char i: letters) {
if (i > target) {
return i;
}
}
return letters[0];
}
}
2、二分查找
由于数组是排序好的,可以使用二分查找,初始时,二分查找的范围是整个列表的下标范围。每次比较当前下标处的字母和目标字母,如果当前下标处的字母大于目标字母,则在当前下标以及当前下标的左侧继续查找,否则在当前下标的右侧继续查找。
需要额外注意的是:由于target可能比数组的最大值大,一旦遍历找不到比target大的,直接返回数组第一个元组即可(数组最小值)。
时间复杂度:O(logN),二分查找的时间复杂度,其中N是数组长度
空间复杂度:O(1),主要是若干变量
python:
class Solution:
def nextGreatestLetter(self, letters: List[str], target: str) -> str:
n = len(letters)
if target >= letters[n-1]:
return letters[0]
left, right = 0, n - 1
while left < right:
mid = (left + right) // 2
if letters[mid] > target:
right = mid
else:
left = mid + 1
return letters[left]
java:
class Solution {
public char nextGreatestLetter(char[] letters, char target) {
int n = letters.length;
if (target >= letters[n-1]) {
return letters[0];
}
int left = 0, right = n - 1;
while (left < right) {
int mid = (right - left)/2 + left;
if (letters[mid] > target) {
right = mid;
}
else {
left = mid + 1;
}
}
return letters[left];
}
}