持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情
162. 寻找峰值
峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞ 。
你必须实现时间复杂度为 O(log n) 的算法来解决此问题。
「示例1:」
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。
「示例2:」
输入:nums = [1,2,1,3,5,6,4]
输出:1 或 5
解释:你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
「提示:」
1. 1 <= nums.length <= 1000
2. -231 <= nums[i] <= 231 - 1
3. 对于所有有效的 i 都有 nums[i] != nums[i + 1]
解题思路
数组从中间分成两个数组 L 和 R。比较 L 最后一个值 l 与 R 的第一个值 r 的大小。如果 l > r 则数组 L 必有一个及以上原数组的峰值,取数组 L 再做上一步。反之则数组 R 必有一个及以上原数组的峰值,取数组 R 再做上一步。当数组长度为 1 时。其值为峰值。
代码实现
var findPeakElement = function(nums) {
let lIndex = 0; // 虚拟数组第一个元素下标
let rIndex = nums.length - 1; // 虚拟数组最后一个元素下标
let mid; // 数组中间元素下标。
while (lIndex < rIndex) { // 当数组长度不为 1 时。
mid = Math.floor((lIndex + rIndex) / 2); // 取当前虚拟数组的中间元素的下标(当数组长度为偶数时取小的那个),可将虚拟元素隔开成两个数组。
if (nums[mid] > nums[mid + 1]){ // 比较左边数组最后一个元素与右边数组的第一个元素的大小
rIndex = mid; // 左边数组最后一个元素大、则取左边数组
} else {
lIndex = mid + 1; // 右边数组第一个元素大、则取右边数组
}
}
return lIndex;
};
如果你对这道题目还有疑问的话,可以在评论区进行留言;