Algorithms
Algorithms 学习笔记——第一课 峰值查找(Peak Finding)
一、一维查找
1.算法
OneDfind(left,right)
OneDfind(0,lenth-1):
//采用divid and conquer 的方法,先从中间开始(即a[mid])
比较左右,如果a[mid]大于左右两边,那么a[mid]是峰值;
如果左边大于a[mid],那么从左边找,调用递归OneDfind(left,mid);
如果右边大于a[mid],那么从右边找,调用递归OneDfind(mid,right);
2.证明
如果a[mid]不是峰值,且左边大于a[mid],那么在左边必然能找到峰值。
这里用反证法,证明左边不能找到峰值
由前提得-----------a[mid-1](左边)> a[mid]
a[mid- 1] 不能为峰值,必有a[mid -2] 大于 a[mid- 1] ,否则a[mid- 1]就是峰值了,
以此递推,会得到a[0] > a[1] > a[2] …>a[mid],由于我们规定a[-1] = 负无穷
那么 a[0] > a[-1] , a[0] > a[1] , a[0]是峰值,矛盾
二、二维查找
1.算法
TwoDfind(arry[0:n][0:n])
1、在当前的arry中找到中间的那一列,a[…,j]
2、按列比:找出这一列里的最大值(不是局部峰值),得到它的坐标a(i,j)
3、按行比:按照二维峰值的定义,再比较a[i,j]的左右邻点,即 a[i-1,j], a[i+1,j]
4、若满足定义,那么a(i,j)为所求
5、若不满足,且左邻点 a[i-1,j] 大于中间a[i,j],那么从左边找,递归调用TwoFind(arry[0:n][0:j])
6、右边大的情况就递归调用TwoFind(arry[0:n][j:n])
2.证明
证明中间列极大值点小于左(右)邻点时,左边(右)必然存在峰值,依然用反证法,当中间列极大值点小于左邻点时,左边不存在峰值
1、按照条件,a( i - 1, j ) > a ( i , j ) > 第j列所有的点(aij为第j列的最大值)。
2、那么,对第j-1列,它的【列】极大值点a( i1 , j - 1) 必然大于它的右邻点 a( i1 , j ) ,又由于它已经是列极大值点了
为了保证它不是峰值,它的左临点必须大于它。
3、现在我们要证明的就变成了第 j -1 列极大值点小于左邻点时,左边不存在峰值
4、按上面的方法一直递推我们就会到达左边界,我们要证明第 1 列极大值点小于左邻点时,左边不存在峰值,我们会得到2)中的结论,第0列的极大值的左邻点必须大于它,可是我们规定-1列为负无穷,所以这一点必然是峰值,矛盾
3.一些细节
如果将算法的第二步里的最大值改成局部峰值,会得到非峰值点,因为它不能保证在反证法第二步里左邻列的最大值(局部峰值也同样)大于它的右邻点。