112 lines
2.7 KiB
JavaScript
112 lines
2.7 KiB
JavaScript
/**
|
|
* LeetCode 852. 山脉数组的峰顶索引
|
|
* @param {number[]} A
|
|
* @return {number}
|
|
*/
|
|
export const peakIndexInMountainArray = function (A) {
|
|
let left = 0
|
|
let right = A.length - 1
|
|
|
|
while (left < right) {
|
|
const mid = left + ((right - left) >> 1)
|
|
if (A[mid] > A[mid - 1] && A[mid] > A[mid + 1]) return mid
|
|
if (A[mid] < A[mid + 1] && A[mid] > A[mid - 1]) {
|
|
left = mid
|
|
} else {
|
|
right = mid
|
|
}
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
/**
|
|
* LintCode 585. 山脉序列中的最大值
|
|
* @param nums: a mountain sequence which increase firstly and then decrease
|
|
* @return: then mountain top
|
|
*/
|
|
export const mountainSequence = function (nums) {
|
|
let left = 0
|
|
let right = nums.length - 1
|
|
|
|
while (left < right) {
|
|
const mid = left + ((right - left) >> 1)
|
|
if (nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1]) return nums[mid]
|
|
if (nums[mid] < nums[mid + 1] && nums[mid] > nums[mid - 1]) {
|
|
left = mid
|
|
} else {
|
|
right = mid
|
|
}
|
|
}
|
|
|
|
return nums[0]
|
|
}
|
|
|
|
/**
|
|
* // This is the MountainArray's API interface.
|
|
* // You should not implement it, or speculate about its implementation
|
|
* function MountainArray() {
|
|
* @param {number} index
|
|
* @return {number}
|
|
* this.get = function(index) {
|
|
* ...
|
|
* };
|
|
*
|
|
* @return {number}
|
|
* this.length = function() {
|
|
* ...
|
|
* };
|
|
* };
|
|
*/
|
|
|
|
/**
|
|
* 1095. 山脉数组中查找目标值
|
|
* @param {number} target
|
|
* @param {MountainArray} mountainArr
|
|
* @return {number}
|
|
*/
|
|
export const findInMountainArray = function (target, mountainArr) {
|
|
let left = 0
|
|
let right = mountainArr.length() - 1
|
|
|
|
// 山峰索引
|
|
let peak = 0
|
|
|
|
while (left < right) {
|
|
const mid = left + ((right - left) >> 1)
|
|
if (mountainArr.get(mid) > mountainArr.get(mid - 1) && mountainArr.get(mid) > mountainArr.get(mid + 1)) {
|
|
peak = mid
|
|
break
|
|
}
|
|
if (mountainArr.get(mid) < mountainArr.get(mid + 1) && mountainArr.get(mid) > mountainArr.get(mid - 1)) {
|
|
left = mid
|
|
} else {
|
|
right = mid
|
|
}
|
|
}
|
|
|
|
// 在山峰左边查找
|
|
const index = binarySearch(mountainArr, target, 0, peak, v => v)
|
|
|
|
// 若存在,则直接返回下标,否则在山峰右边查找
|
|
return index !== -1 ? index : binarySearch(mountainArr, target, peak + 1, mountainArr.length() - 1, v => -v)
|
|
|
|
// 二分法查找
|
|
// 其中 fn 是用来对升序还是降序的特殊处理
|
|
function binarySearch (mountainArr, target, l, r, fn) {
|
|
target = fn(target)
|
|
while (l <= r) {
|
|
const mid = (l + (r - l) / 2) | 0
|
|
const cur = fn(mountainArr.get(mid))
|
|
if (cur === target) {
|
|
return mid
|
|
} else if (cur < target) {
|
|
l = mid + 1
|
|
} else {
|
|
r = mid - 1
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
}
|