题目来源: LeetCode 75 30 天 JavaScript 挑战
代码 162. 寻找峰值
思路
二分查找,使用 left
, right
两个指针,每次算出 mid
, 如果 nums[mid]
大于 nums[mid + 1]
那么峰值在左边,执行 right = mid
, 否则峰值在右边, 执行 left = mid + 1
, 最后然后 left
指针。
代码
js
/**
* @param {number[]} nums
* @return {number}
*/
var findPeakElement = function(nums) {
let left = 0
let right = nums.length - 1
while(left < right) {
const mid = Math.floor(left + (right - left) / 2)
if (nums[mid] > nums[mid + 1]) {
right = mid
} else {
left = mid + 1
}
}
return left
};
875. 爱吃香蕉的珂珂
思路
二分查找,每次判断是否能在时间内吃完 k 个香蕉,能吃完时间加一,不能吃完时间加上Math.ceil(piles[i] / k)
,最后返回 k 最小的值。
代码
js
/**
* @param {number[]} piles
* @param {number} h
* @return {number}
*/
var minEatingSpeed = function(piles, h) {
let mid
let left = 1
let right = Math.max(...piles)
while(left < right) {
mid = Math.floor(left + (right - left) / 2)
// 判断能否在 mid 值吃完香蕉
if (canEat(mid, h, piles)) {
right = mid
} else {
left = mid + 1
}
}
return left
};
function canEat(k, h, piles) {
let total = 0
for (let i = 0; i < piles.length; i++) {
if (piles[i] <= k) {
total += 1
} else {
total += Math.ceil(piles[i] / k)
}
}
// 返回吃完用时是否大于总时间
return total <= h
}
17. 电话号码的字母组合
思路
递归回溯,终止条件是当前路径的长度等于 digits
的长度,每次从 digits
取出一个数字开始递归调用,到达终止条件, 先将结果保存到 res
数组,然后开始回溯 path.pop()
。
代码
js
const map = new Map()
map.set(2, 'abc')
map.set(3, 'def')
map.set(4, 'ghi')
map.set(5, 'jkl')
map.set(6, 'mno')
map.set(7, 'pqrs')
map.set(8, 'tuv')
map.set(9, 'wxyz')
/**
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function(digits) {
if(!digits.length) {
return []
}
let res = []
let path = []
const recur = (path, start) => {
// 到达终止条件
if (path.length === digits.length) {
res.push(path.slice(0).join(''))
return
}
const letters = map.get(parseInt(digits[start]))
for (let i = 0; i < letters.length; i++) {
path.push(letters[i])
// 递归
recur(path, start + 1)
// 回溯
path.pop()
}
}
recur(path, 0)
return res
};
本文完,感谢阅读。