我是Python的新手,因此这个问题。我正在尝试解决一个标准的面试问题,即在数组中找到一个高峰。峰值定义为大于其左右邻居的数字。我正试图找到最大的这样的峰值。
这是我的代码:
def main():
arr = [7, 12, 13, 8, 2, 16, 24, 11, 5, 1]
print(find_peak(arr))
def find_peak(arr):
return _find_peak(arr, 0, len(arr))
def _find_peak(arr, start, stop):
mid = (start + stop) // 2
if arr[mid] > arr[mid - 1] and arr[mid] > arr[mid + 1]:
return arr[mid]
elif arr[mid] < arr[mid - 1]:
_find_peak(arr, 0, mid - 1)
elif arr[mid] < arr[mid + 1]:
_find_peak(arr, mid + 1, stop)
if __name__ == '__main__':
main()
此程序的输出为None
,其中预期输出为24
。任何帮助表示赞赏。
答案 0 :(得分:4)
arr = [7, 12, 13, 8, 2, 16, 24, 11, 5, 1]
一行应该足够了:
max_peak = max(x2 for x1, x2, x3 in zip(arr, arr[1:], arr[2:]) if x1 < x2 > x3)
当您不熟悉Python时,可能更容易理解:
peak = float('-inf')
for x1, x2, x3 in zip(arr, arr[1:], arr[2:]):
if x1 < x2 > x3:
peak = max(peak, x2)
print(peak)
输出:
24
您还可以使用单线来获取所有峰值:
>>> [x2 for x1, x2, x3 in zip(arr, arr[1:], arr[2:]) if x1 < x2 > x3]
[13, 24]
并在结果上获得max()
的最大值。
让我们看一下解决方案的一些组成部分。我在这里使用Python 3,每个人都应该这样做。 ;)
您可以对列表进行切片。
>>> arr = [7, 12, 13, 8, 2, 16, 24, 11, 5, 1]
这为您提供了所有列表,但第一个元素:
>>> arr[1:]
[12, 13, 8, 2, 16, 24, 11, 5, 1]
这里从元素三开始:
>>> arr[2:]
[13, 8, 2, 16, 24, 11, 5, 1]
zip()函数将多个序列压缩在一起。要想象发生了什么,您可以将zip对象转换为列表:
>>> list(zip(arr, arr[1:], arr[2:]))
[(7, 12, 13),
(12, 13, 8),
(13, 8, 2),
(8, 2, 16),
(2, 16, 24),
(16, 24, 11),
(24, 11, 5),
(11, 5, 1)]
Python支持元组解包。这允许将单个名称分配给元组的所有成员:
>>> x1, x2, x3 = (7, 12, 13)
>>> x1
7
>>> x2
12
>>> x3
13
另一个不错的功能是比较两个以上的对象:
>>> 10 < 12 > 8
True
这相当于:
>>> (10 < 12) and (12 > 8)
True
Python提供list comprehensions:
>>> [x * 2 for x in range(2, 6)]
[4, 6, 8, 10]
Generator expression以类似的方式工作,但不生成列表但是迭代器,并且可以在不使用大量内存的情况下使用:
>>> sum(x * 2 for x in range(2, 6))
28
答案 1 :(得分:0)
您错过了两个elif
个案件的退货声明
答案 2 :(得分:0)
我认为13也是一个峰值(大于12和8)。
尝试这种方法:
def main():
arr = [7, 12, 13, 8, 2, 16, 24, 11, 5, 1]
print(find_peaks(arr))
def find_peaks(arr):
return list(_search(arr))
def _search(arr):
last = len(arr) - 1
for i, e in enumerate(arr):
if not any((i > 0 and arr[i-1] > e, i < last and arr[i+1] > e)):
yield e
if __name__ == '__main__':
main()
如果你什么都不懂,请问!
答案 3 :(得分:0)
另一种方法 - 只使用一个功能:
def main():
arr = [7, 12, 13, 8, 2, 16, 24, 11, 5, 1]
print(find_peaks(arr))
def find_peaks(arr):
last = len(arr) - 1
return [
e for i, e in enumerate(arr)
if not any((i > 0 and arr[i-1] > e, i < last and arr[i+1] > e))
]
if __name__ == '__main__':
main()
答案 4 :(得分:0)
我认为你不能在O(log N)时间内找到一个峰值,因为根据定义,项目不能按顺序排列,并且没有办法预测列表中任何项目的高峰值除了将项目N与项目N + 1进行比较之外,项目可能是反身的 - 它告诉您N或N + 1可能是一个峰值。这会让你进行N / 2比较,然后必须再跟N / 2比较来检查峰值的另一侧。
以下是local_maxima(iterable)
函数,您可以使用max()
查找峰值。如果它们大于它们的一个邻居,它会将起始/结束元素视为峰值。
data = [7, 12, 13, 8, 2, 16, 24, 11, 5, 1, None, 2, None, 3, 4, None, 5, 1, None]
firstpeak = [12, 7, 9, 8]
lastpeak = [1, 2, 3, 4]
def local_maxima(it):
"""Find local maxima in iterable _it_. Compares with None using
`is (not) None`, and using operator `<`."""
peaking = False
last = None
for item in it:
# Deal with last item peaking
if peaking and (item is None or item < last):
yield last
peaking = False
elif item is None:
peaking = False
elif last is None or last < item:
peaking = True
else:
peaking = False
last = item
if peaking:
yield last
print([x for x in local_maxima(data)])
print("Highest:", max(local_maxima(data)))
print([x for x in local_maxima(firstpeak)])
print("Highest:", max(local_maxima(firstpeak)))
print([x for x in local_maxima(lastpeak)])
print("Highest:", max(local_maxima(lastpeak)))