题目要求——search peak element
在一组随机的列表当中,有一定规模的元素在其中,在该列表中没有重复性元素(no duplicates),但是会存在多个峰值(peak element),要求能够返回任一峰值以及其所对应的index
方法一 | 方法二 |
---|---|
从头到尾遍历所有元素的内容 比较其左右值和当前元素的大小 如果当前元素的值大于左右值 则找到了峰值 | 分而治之,每次遍历将问题切分为二 比较其左右值的大小,观察其趋势 再确定去哪一个区间去找 |
具有一般性的随机列表生成
import random
def create_list(num, start, end):
'''
create a random num list
:return: result list
'''
global num_list
num_list = []
while len(num_list) != num:
n = random.randint(start , end)
num_list.append(n)
num_list = list(set(num_list))
random.shuffle(num_list)
return num_list
scale = int(input('请输入您想要达到的列表规模:'))
start = int(input('开始数字:'))
end = int(input('结束数字:'))
res_list = create_list(scale, start, end)
print('生成的随机且元素不重复的自定义规模列表:\n',res_list)
峰值分析
情况一 | 情况二 | 情况三 | 情况四 |
---|---|---|---|
红色点即为峰值点 | 两侧区间都要去考虑 | 在右侧区间考虑 | 在左侧区间考虑 |
1、方法一
从头到尾遍历一整个数组,只要出现左右两侧的值是小于当前遍历到的值,那么就为峰值,输出其内容以及下标,四种情况都做考虑,并做边界限制就可以了,这个方法只讲思路。
2、方法二
使用递归完成,一分为二,分而治之
def divide_search_peak_element(res_list, left, right):
'''
通过递归实现
:param res_list:
:return:
'''
if left == right:
return left
if left + 1 == right:
if res_list[left] > res_list[right]:
return left
return right
mid = left + (right - left)//2
if res_list[mid - 1 ] < res_list[mid] > res_list[mid + 1]:
return mid
if res_list[mid - 1] < res_list[mid] < res_list[mid + 1]:
return divide_search_peak_element(res_list, mid + 1, right)
if res_list[mid - 1] > res_list[mid] > res_list[mid + 1]:
return divide_search_peak_element(res_list, left, mid - 1)
result = divide_search_peak_element(res_list, 0, len(res_list) - 1)
print('返回的峰值下标:{index}\n峰值内容:{value}'.format(index = result, value = res_list[result]))