峰查找问题,听MIT算法导论课的第一节,介绍算法时引入。强调了算法思想(algorithmic thinking),提到了分治(divide and conquer)和递归(recursive)思想。
解决以下问题:
- 什么是峰?
- 如何寻找到一个?
- ID和2D查找。
1).什么是峰?
1D:在一维数组中,若a[n]>a[n-1]且a[n]>a[n+1]那么a[n]就是一个峰
2D:在矩阵中,如果一个元素大于或等于其临近(4临近)的元素,那么它就是一个峰。
10就是一个峰
2).如何寻找?
最暴力的方法当然是找出数组中的最大值,这种遍历整个数组的时间复杂度为O(n)。但是只要求找到一个,没有必要找到最大的,可以用对半寻找,时间复杂度为O(lgn)。
从峰的定义可以看出,峰两边的变化趋势是确定的,所以可以利用这一点确定峰的位置,如图中:
当N/2<=2/N+1的时候,可以看到数组有上升的趋势,峰应该处于N/2的右边,故可以取右边N/2~N的部分继续下去。
同理当N/2-1>=N/2时,数组有下降的趋势,峰应该处于N/2的左边,故可以去左边1~N/2继续下去。
当然,当运气很好N/2>=N/2-1且N/2>=N/2+1时,N/2处即为峰值。
用python实现:
def oned_peak_finding(nums):
num=len(nums)
if num==2:
return max(nums[0],nums[1])
if nums[num//2]<nums[num//2-1]:
oned_peak_finding(nums[0:num//2+1])
if nums[num//2]<=nums[num//2+1]:
oned_peak_finding(nums[num//2:num])
else:
return nums[num//2]
if __name__=="__main__":
nums=[1,2,3,4,5,6,2,3,5,3]
print(oned_peak_finding(nums))
返回
>>>6