Skip to content

Commit eb5a951

Browse files
authored
Peak of unimodal list DNC algorithm (#3691)
* Peak of unimodal list DNC algorithm * fix black formatting issues * add doctest testing * make file black compliant
1 parent 4851942 commit eb5a951

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

Diff for: divide_and_conquer/peak.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""
2+
Finding the peak of a unimodal list using divide and conquer.
3+
A unimodal array is defined as follows: array is increasing up to index p,
4+
then decreasing afterwards. (for p >= 1)
5+
An obvious solution can be performed in O(n),
6+
to find the maximum of the array.
7+
(From Kleinberg and Tardos. Algorithm Design.
8+
Addison Wesley 2006: Chapter 5 Solved Exercise 1)
9+
"""
10+
from typing import List
11+
12+
13+
def peak(lst: List[int]) -> int:
14+
"""
15+
Return the peak value of `lst`.
16+
>>> peak([1, 2, 3, 4, 5, 4, 3, 2, 1])
17+
5
18+
>>> peak([1, 10, 9, 8, 7, 6, 5, 4])
19+
10
20+
>>> peak([1, 9, 8, 7])
21+
9
22+
>>> peak([1, 2, 3, 4, 5, 6, 7, 0])
23+
7
24+
>>> peak([1, 2, 3, 4, 3, 2, 1, 0, -1, -2])
25+
4
26+
"""
27+
# middle index
28+
m = len(lst) // 2
29+
30+
# choose the middle 3 elements
31+
three = lst[m - 1 : m + 2]
32+
33+
# if middle element is peak
34+
if three[1] > three[0] and three[1] > three[2]:
35+
return three[1]
36+
37+
# if increasing, recurse on right
38+
elif three[0] < three[2]:
39+
if len(lst[:m]) == 2:
40+
m -= 1
41+
return peak(lst[m:])
42+
43+
# decreasing
44+
else:
45+
if len(lst[:m]) == 2:
46+
m += 1
47+
return peak(lst[:m])
48+
49+
50+
if __name__ == "__main__":
51+
import doctest
52+
53+
doctest.testmod()

0 commit comments

Comments
 (0)