11 寻找峰值(Find Peak Element)

1 题目

  寻找峰值(Find Peak Element)

lintcode:题号——75,难度——medium

2 描述

  给定一个整数数组(size为n),其具有以下特点:相邻位置的数字是不同的;A[0] < A[1] 并且 A[n - 2] > A[n - 1];假定P是峰值的位置则满足A[P] > A[P-1]且A[P] > A[P+1],返回数组中任意一个峰值的位置。数组保证至少存在一个峰;如果数组存在多个峰,返回其中任意一个就行;数组至少包含 3 个数。

  样例1:

输入:A = [1, 2, 1, 3, 4, 5, 7, 6]
输出:1
解释:

返回任意一个峰顶元素的下标,元素2的下标为1,下标6也同样正确。

  样例2:

输入:A = [1,2,3,4,1]
输出:3
解释:

返回峰顶元素4的下标3。

3 思路

  寻找峰值点,峰值点的特征是点的左边处于递增状态、右边处于递减状态。题中对数组做了一些限定:A[0] < A[1],即起点是递增状态; A[n - 2] > A[n - 1],即到达终点时候是递减状态,且相邻位置的数字不同。需要找到数组中的任意一个峰值即可,可以通过递增递减的状态来寻找,即在任意一个区间中,如果起点递增、终点递减,那这个区间内一定有峰值,通过二分法拆分为“half half”的方式,每次留下一定存在峰值的区间,抛掉不一定存在峰值的区间,最后即可找到。

  1. 取中点;
  2. 比较中点与下一个点,判断当前处于递增还是递减;
  3. 找到起点递增、终点递减这样的一定存在峰值的区间,抛掉另一半不一定存在峰值的区间。
  4. 重复上述过程,直到找到峰值。

3.1 图解

输入:A = [1, 2, 1, 3, 4, 5, 7, 6]
输出:6
解释:

返回任意一个峰顶元素的下标即可,峰值元素7的下标为6。

中间位置元素'3',下一个元素'4',递增
3..4递增,7..6递减,区间必有峰值
中间位置元素'5',下一个元素'7',递增
5..7递增,7..6递减,区间必有峰值
中间位置元素'7',下一个元素'6',递减
5..7递增,7..6递减,区间必有峰值
剩下两个元素取峰值
'1, 2, 1, 3, 4, 5, 7, 6'
抛掉'1, 2, 1'
缩小区间至'3, 4, 5, 7, 6'
抛掉'3, 4'
缩小区间至'5, 7, 6'
缩小区间至'5, 7'
抛掉'6'
找到目标元素'7',下标'6'

3.2 时间复杂度

  算法的时间复杂度为O(log n)。

3.3 空间复杂度

  算法的空间复杂度为O(1)。

4 源码

  注意事项:

  1. 最后两个元素中取峰值的时候,在逻辑上可以直接取end。

因为在最后一次缩小区间的时候,必定是end = mid的情况。如果最后一次缩小区间是start = mid的情况,则说明在缩小后的区间内start点还是处于递增的状态,start必定还不是峰值,区间还能再缩。

  1. 返回的是序号,不是元素值。

  C++版本:

/**
* @param A: 整数数组
* @return: 任意峰值点的下标序号
*/
int findPeak(vector<int> &A) {
	// write your code here
	if (A.size() < 3)
	{
		return -1;
	}

	int start = 0;
	int end = A.size() - 1;
	int mid = 0;
	while (start + 1 < end)
	{
		mid = start + (end - start) / 2;
		if (A.at(mid) < A.at(mid + 1))
		{
			start = mid;
		}
		if (A.at(mid) > A.at(mid + 1))
		{
			end = mid;
		}
	}

	return end;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值