[JavaScript 刷题] 二分搜索 - 大于给定元素的最小元素,Leetcode 744
Posted GoldenaArcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JavaScript 刷题] 二分搜索 - 大于给定元素的最小元素,Leetcode 744相关的知识,希望对你有一定的参考价值。
[javascript 刷题] 二分搜索 - 大于给定元素的最小元素,Leetcode 744
题目地址:744. Find Smallest Letter Greater Than Target
题目
如下:
Given a characters array letters that is sorted in non-decreasing order and a character
target
, return the smallest character in the array that is larger thantarget
.Note that the letters wrap around.
- For example, if
target == 'z'
andletters == ['a', 'b']
, the answer is'a'
.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.
解题思路
依旧日常开始捋题,这道题不算长,不过需要注意的是,这道题属于是 二分查找 的变种,所以实现起来和普通的二分查找稍有不同。
-
如上面分析的那样,这道题依旧是用 二分查找 进行解题
这属于 查找最小值 的变种,类似的还有 最大值、第一个 最小值、最后一个 最小值 等相关排列组合,但是基本思路都是 二分查找 的思路
-
数组是 非降序 的排序,也就是说 下一个字符一定是 ≥ \\geq ≥ 当前字符
-
返回值是 当前数组中大于
target
的最小值例:Input: letters =
["c","f","j"]
, target ="a"
,返回值是"c"
,因为"c"
是下一个大于"a"
的值以题目中的例子来说,如果数组中不存在大于
target
的值,那么就返回数组中的最小值 -
Constraints 中说了,数组和目标的值都是小写的英文字母,所以至少在这个题目中不用担心大小写的问题了
-
Constraints 其实提供了一个挺好的边界条件的思路,例如说数组长度必须为 2 之类的
使用 JavaScript 解题
/**
* @param {character[]} letters
* @param {character} target
* @return {character}
*/
var nextGreatestLetter = function (letters, target) {
if (letters.length < 2)
throw new Error('letters must contains at least two different characters.');
let lo = 0,
hi = letters.length - 1,
mid;
while (lo <= hi) {
mid = Math.floor((lo + hi) / 2);
// 当小于等于 target 的时候,都会往前推进一格
// 也就是说,当跳出循环时,永远也不可能等到 letters[lo] === target 这个情况
// 只会出现 letters[lo] > target 的情况
// 题目要求返回的值必须要 > target,也就是说这一题返回的是 letters[lo]
if (letters[mid] <= target) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
// 另外也存在一种情况,那就是当 target 永远 > 数组中的所有数字
// 这种情况下,hi 会一直等于 letters.length,而当跳出循环时,lo === letters.length
// 所以需要另外一个判断,当 lo === letters.length 时就代表数组中所有的值都比 target 小
// 返回值就是 letters[0],如题目中所标注的那样
return lo === letters.length ? letters[0] : letters[lo];
};
console.log(nextGreatestLetter((letters = ['a', 'b']), (target = 'z')));
console.log(nextGreatestLetter((letters = ['c', 'f', 'j']), (target = 'a')));
console.log(nextGreatestLetter((letters = ['c', 'f', 'j']), (target = 'c')));
console.log(nextGreatestLetter((letters = ['c', 'f', 'j']), (target = 'd')));
console.log(nextGreatestLetter((letters = ['c', 'f', 'j']), (target = 'g')));
console.log(nextGreatestLetter((letters = ['c', 'f', 'j']), (target = 'j')));
另外这一题的确是可以通过利用边界条件进行提速的:
这个想法来自于一个讨论:
我觉得很有道理,于是加了一个边界条件:
var nextGreatestLetter = function (letters, target) {
if (letters[letters.length - 1] < target) return letters[0];
// 后面的代码都是一样的
};
然后果然快了一些:
以上是关于[JavaScript 刷题] 二分搜索 - 大于给定元素的最小元素,Leetcode 744的主要内容,如果未能解决你的问题,请参考以下文章
[JavaScript 刷题] 二分搜索 - 搜索二维矩阵, leetcode 74
[JavaScript 刷题] 二分搜索 - 求开方,Leetcode 69
[JavaScript 刷题] 二分搜索 - 第一个错误的版本,Leetcode 278