0
点赞
收藏
分享

微信扫一扫

[查找]BM19 寻找峰值-中等

​​BM19 寻找峰值​​

知识点​​数组​​​​查找​​

描述

给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于2.假设 nums[-1] = nums[n] = [查找]BM19 寻找峰值-中等_数组3.对于所有有效的 i 都有 nums[i] != nums[i + 1]4.你可以使用O(logN)的时间复杂度实现此问题吗?

数据范围:[查找]BM19 寻找峰值-中等_数组_02

[查找]BM19 寻找峰值-中等_数组_03


如输入[2,4,1,2,7,8,4]时,会形成两个山峰,一个是索引为1,峰值为4的山峰,另一个是索引为5,峰值为8的山峰,如下图所示:[查找]BM19 寻找峰值-中等_二分查找_04

示例1

输入:

[2,4,1,2,7,8,4]

复制返回值:

1

复制说明:

4和8都是峰值元素,返回4的索引1或者8的索引5都可以

示例2

输入:

[1,2,3,1]

复制返回值:

2

复制说明:

3 是峰值元素,返回其索引 2

题解

O(n)时间复杂度解法

思路很简单,遍历数组,如果左右的值都小于当前的值,则返回当前下标。不过题目要求的最佳时间复杂度为log(n),不满足该要求。

#include <bits/stdc++.h>

int findPeakElement(std::vector<int> &nums)
{
if (nums.size() == 1)
{
return 0;
}

int pre_height = INT_MIN;
for (int i = 0; i < nums.size(); ++i)
{
int cur_height = nums[i];
if (i == nums.size() - 1)
{
return nums[i - 1] > cur_height ? (i - 1) : i;
}
else
{
if (i == 0)
{
if (cur_height > nums[i + 1])
{
return i;
}
}
else if (cur_height > nums[i - 1] && cur_height > nums[i + 1])
{
return i;
}
}
}
return -1;
}

log(n)时间复杂度解法

实际上就是二分查找。

使用二分查找的一个前提条件是,由于峰值表示的是当前下标的值比左右下标的值都大。因此,我们找到任意2个节点,当我们选择其中较大的一个节点的时候,往较大的这个方向上一定会存在波峰。

具体思路如下:

  • 1. 先设置左右界限[left,right]
  • 2. 找到中间节点,判断中间节点与其下一节点值的大小,如果中间节点大,则设置界限为[left,mid],否则设置为[mid+1,right]
  • 3. 重复上述操作,直到left >= right

代码如下:


int findPeakElement_logn(std::vector<int> &nums)
{
int left = 0;
int right = nums.size() - 1;
//二分法
while (left < right)
{
int mid = (left + right) / 2;
//右边是往下,不一定有坡峰
if (nums[mid] > nums[mid + 1])
right = mid;
//右边是往上,一定能找到波峰
else
left = mid + 1;
}
//其中一个波峰
return right;
}
举报

相关推荐

0 条评论