我最近开始研究麻省理工学院的6.006讲座,在第一讲中,讲师提出了峰值发现算法。
根据他的定义:
给定一个数组[a,b,c,d,e,f,g],其中a-g是数字,b是一个峰值 if和仅当< = b和b> = c。
他给出了递归方法:
if a[n/2] < a[n/2 -1] then look for a peak from a[1] ... a[n/2 -1]
else if a[n/2] < a[n/2+1] then look for a peak from a[n/2+1] ... a[n]
else a[n/2] is a peak
他说算法是T(n)= T(n / 2)+ o(1)= o(lgn)
在他的pdf中,他还给出了一个完整的例子:[6,7,4,3,2,1,4,5]
7和5都是峰值。但上面的算法是不是仅仅因为中间元素恰好满足第一个分支而发现7为峰值?
所以如果我们应该找到所有的峰值,我们还会穿过整个阵列吗?这是否意味着最坏的情况N?
他的定义是否意味着我们只需找到一个峰值?
我相信这个问题可以被视为在Riverst的算法入门书中找到最大和最小元素。
答案 0 :(得分:17)
是的,此算法只能找到一个峰值。
如果你想找到所有峰值,你必须检查所有元素,所以它将是O(n)。
注意:峰值不一定是全局最大值。
答案 1 :(得分:6)
我不太相信这种算法是否是找到有趣峰值的最佳方法。它倾向于支持中间元素的比较,这可能将搜索推向次优方向,并且最终算法总是最终在Edges而不是中间找到峰值。 简单的例子
[1,2,3,4,5,6,7,8] =&gt;峰值为8
[6,21,7,8,9,10,11,13] =&gt;峰值为13,而21的峰值更有趣
当然,算法保证找到一个峰值,因为它向更高的方向移动,但正如我在示例中所示,峰值可能不是有趣的峰值!
答案 2 :(得分:1)
我昨天刚开始这个课程,问题陈述是:
问题:如果存在峰值(它是否始终存在?)
所以,算法所做的只是尝试在最短的时间内找到一个峰值,第一个可用。
这就是为什么这个算法只找到一个峰值。
答案 3 :(得分:0)
此算法与binary search algorithm非常相似。二进制搜索仅适用于已排序的数组,此峰值搜索算法看起来应该与另一个定义一起使用:x[p]
是0 <= i < p
x[i] <= x[i + 1]
和{{1}的峰值}} p <= i < x.size
。如果我们认为问题中的定义是错误的,而且这个定义是对的:一切都好。看起来它是错误的,因为它在第二种情况下给出了几个峰值,你是对的。
答案 4 :(得分:0)
我最近也开始研究它,这是我发现的: 如果一维数组元素不小于其邻居元素,则它是一个峰,对于排序后的数组,最后一个元素始终是峰,在此过程中提供的解决方案与使用分而治之二进制搜索的工作原理非常相似,并且问题还说找到一个峰,我们可以有多个峰,但是我们需要第一个峰元素,然后完成。
例如,我们有一个长度为n的一维数组:
DO:
m = n/2
neigborLeft = m-1
neigborRight = m+1
if neigborLeft >= 0 && a[neigborLeft] > a[m]
//recursion with left elements
else if neigborRight <= n-1 && a[neigborRight] > a[m]
//recursion with right elements
else
// peak value is a[m]
了解更多: geeksforgeeks.org/find-a-peak-in-a-given-array /