forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Peak of unimodal list DNC algorithm (TheAlgorithms#3691)
* Peak of unimodal list DNC algorithm * fix black formatting issues * add doctest testing * make file black compliant
- Loading branch information
Showing
1 changed file
with
53 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
""" | ||
Finding the peak of a unimodal list using divide and conquer. | ||
A unimodal array is defined as follows: array is increasing up to index p, | ||
then decreasing afterwards. (for p >= 1) | ||
An obvious solution can be performed in O(n), | ||
to find the maximum of the array. | ||
(From Kleinberg and Tardos. Algorithm Design. | ||
Addison Wesley 2006: Chapter 5 Solved Exercise 1) | ||
""" | ||
from typing import List | ||
|
||
|
||
def peak(lst: List[int]) -> int: | ||
""" | ||
Return the peak value of `lst`. | ||
>>> peak([1, 2, 3, 4, 5, 4, 3, 2, 1]) | ||
5 | ||
>>> peak([1, 10, 9, 8, 7, 6, 5, 4]) | ||
10 | ||
>>> peak([1, 9, 8, 7]) | ||
9 | ||
>>> peak([1, 2, 3, 4, 5, 6, 7, 0]) | ||
7 | ||
>>> peak([1, 2, 3, 4, 3, 2, 1, 0, -1, -2]) | ||
4 | ||
""" | ||
# middle index | ||
m = len(lst) // 2 | ||
|
||
# choose the middle 3 elements | ||
three = lst[m - 1 : m + 2] | ||
|
||
# if middle element is peak | ||
if three[1] > three[0] and three[1] > three[2]: | ||
return three[1] | ||
|
||
# if increasing, recurse on right | ||
elif three[0] < three[2]: | ||
if len(lst[:m]) == 2: | ||
m -= 1 | ||
return peak(lst[m:]) | ||
|
||
# decreasing | ||
else: | ||
if len(lst[:m]) == 2: | ||
m += 1 | ||
return peak(lst[:m]) | ||
|
||
|
||
if __name__ == "__main__": | ||
import doctest | ||
|
||
doctest.testmod() |