分治算法用于在数组中查找峰值。

Posted

技术标签:

【中文标题】分治算法用于在数组中查找峰值。【英文标题】:Divide and conquer algorithm applied in finding a peak in an array. 【发布时间】:2013-05-29 01:05:31 【问题描述】:

对于数组a:a1, a2, ... ak, ... an, ak 是一个峰当且仅当 ak-1 ≤ ak ≥ ak+1 时1 1 ≥ a2 a1 是一个峰,如果 a an 是一个峰>n-1 ≤ an。目标是从数组中找到一个峰。

分治算法如下:

find_peak(a,low,high):
    mid = (low+high)/2
    if a[mid-1] <= a[mid] >= a[mid+1] return mid // this is a peak;
    if a[mid] < a[mid-1] 
        return find_peak(a,low,mid-1) // a peak must exist in A[low..mid-1]
    if a[mid] < a[mid+1]
        return find_peak(a,mid+1,high) // a peak must exist in A[mid+1..high]

为什么这个算法是正确的?我认为它可能会丢失存在峰值的数组的一半。

【问题讨论】:

真正归结为断言;如果 a[mid] 这个算法对数据的结构方式做了很多假设。 re “我认为它可能会因丢失存在峰值的阵列的一半而受到影响。”你之前说过你只想找到一个峰。因此,只要另一半有一个峰值,您是否丢失了一半数组也没关系。另外,您是否尝试过编写算法并在带有一些不同测试用例的调试器中运行它?可能会给你一些关于它在做什么的直觉。 这是假设数组持有一个平滑变化函数。 【参考方案1】:

该算法是正确的,尽管它需要一些微积分来证明。 第一种情况是微不足道的→峰值。 第二种情况是“半峰”,意味着它有下坡,但没有上坡。

这里有两种可能性:

函数单调递减,直到 amid → a1 ≥ a2 为峰值。 函数直到amid才单调递减→有一个1≥k≥mid,其中ak≥ak-1子>。让我们选择这个陈述成立的最大 k → ak+1k ≥ ak-1 → 这就是峰值.

类似的论点可以应用于具有相反“半峰”的第三种情况。

【讨论】:

值得补充的是,如果我们在一侧或另一侧有一系列常量,这可能会崩溃吗? 感谢您的回答。我明白你的观点,直觉上是正确的。你能具体说明如何证明吗? @TooTone 不,它仍然有效 - 根据问题定义,3 个相等的连续值也有资格获得峰值 @icepack 我的立场是正确的:它对峰值的定义有点不直观。

以上是关于分治算法用于在数组中查找峰值。的主要内容,如果未能解决你的问题,请参考以下文章

用于查找循环排序数组中正数总和的分治算法[关闭]

递归分治算法之二维数组二分查找(Java版本)

使用分治算法在未排序的数组中查找最大和

分治算法 ------二分查找

算法设计与分析分治法

数据结构与算法:寻找峰值