add: 山脉数组中查找目标值
This commit is contained in:
parent
81d8dfae72
commit
de9ff35202
@ -213,6 +213,12 @@ LeetCode 与 LintCode 解题记录。此为个人练习仓库,代码中对重
|
||||
|
||||
- LeetCode 136. 只出现一次的数字 https://leetcode-cn.com/problems/single-number/
|
||||
|
||||
- [山脉数组中查找目标值](src/array/find-in-mountain-array.js)
|
||||
|
||||
- LeetCode 1095. 山脉数组中查找目标值 https://leetcode-cn.com/problems/find-in-mountain-array/
|
||||
- LeetCode 852. 山脉数组的峰顶索引 https://leetcode-cn.com/problems/peak-index-in-a-mountain-array/
|
||||
- LintCode 585. 山脉序列中的最大值 https://www.lintcode.com/problem/maximum-number-in-mountain-sequence/description
|
||||
|
||||
## 栈
|
||||
|
||||
- [最大矩阵](src/stack/maximal-rectangle.js)
|
||||
@ -260,4 +266,3 @@ LeetCode 与 LintCode 解题记录。此为个人练习仓库,代码中对重
|
||||
|
||||
- LeetCode 23. 合并K个排序链表 https://leetcode-cn.com/problems/merge-k-sorted-lists/
|
||||
- LintCode 104. 合并k个排序链表 https://www.lintcode.com/problem/merge-k-sorted-lists/description
|
||||
|
||||
|
111
src/array/find-in-mountain-array.js
Normal file
111
src/array/find-in-mountain-array.js
Normal file
@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
}
|
30
test/array/find-in-mountain-array.test.js
Normal file
30
test/array/find-in-mountain-array.test.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { peakIndexInMountainArray, mountainSequence, findInMountainArray } from '../../src/array/find-in-mountain-array'
|
||||
|
||||
test('山脉数组的峰顶索引', () => {
|
||||
expect(peakIndexInMountainArray([0, 1, 0])).toBe(1)
|
||||
expect(peakIndexInMountainArray([0, 2, 1, 0])).toBe(1)
|
||||
})
|
||||
|
||||
test('山脉序列中的最大值', () => {
|
||||
expect(mountainSequence([1, 2, 4, 8, 6, 3])).toBe(8)
|
||||
expect(mountainSequence([10, 9, 8, 7])).toBe(10)
|
||||
})
|
||||
|
||||
function MountainArray (arr) {
|
||||
this.arr = arr
|
||||
// @param {number} index
|
||||
// @return {number}
|
||||
this.get = function (index) {
|
||||
return this.arr[index]
|
||||
}
|
||||
|
||||
// @return {number}
|
||||
this.length = function () {
|
||||
return this.arr.length
|
||||
}
|
||||
};
|
||||
|
||||
test('山脉数组中查找目标值', () => {
|
||||
expect(findInMountainArray(3, new MountainArray([1, 2, 3, 4, 5, 3, 1]))).toBe(2)
|
||||
expect(findInMountainArray(3, new MountainArray([0, 1, 2, 4, 2, 1]))).toBe(-1)
|
||||
})
|
Loading…
Reference in New Issue
Block a user