Solution: Find the Peak Element
This review discusses the solution of the peak element challenge in detail.
We'll cover the following...
Solution: 1
One simple way to solve this problem is:
# Function to find the peak element in the listdef find_peak(lst):"""Finds a peak element:param lst: List of integers:return: Returns a peak element in a given list"""# If the list in emptyif len(lst) is 0:return -1# If the list has only one elementif len(lst) is 1:return lst[0]for i in range(1, len(lst) -1):if lst[i] >= lst[i-1] and lst[i] >= lst[i+1]:return lst[i]if lst[0] >= lst[1]:return lst[0]elif lst[len(lst) - 1] >= lst[len(lst) - 2]:return lst[len(lst) - 1]return -1# Driver code to test above functionif __name__ == '__main__':# Example: 1lst = [7, 11, 22, 13, 4, 0]print('One peak point is: ', find_peak(lst))# Example: 2lst = [0, 3, 100, 2, -1, 0]print('One peak point is: ', find_peak(lst))# Example: 3lst = [6, 5, 4, 3, 2, 1]print('One peak point is: ', find_peak(lst))
Explanation
- Start from the beginning, compare each element with its neighbors
- Return the peak element wherever you find it in the list
If the list is sorted in an increasing order with no repetition, then the last element is always a peak element:
In this case, the peak element is at the end of the list.
Time complexity
This solution gives us a worst-case time complexity of .
Any better solution?
Solution: 2 (efficient)
Using divide and conquer, we can speed up the whole process. Have a look at the solution given below:
# Utility functiondef find_peak_recursive(low, high, lst):"""Finds a peak element:param low: Starting index of a given list:param high: Ending index of a given list:param lst: List of integers:return: Returns a peak element in a given list"""# Finding the middle indexmiddle = low + (high - low) // 2# If there are neighboursif (middle == len(lst) - 1 or lst[middle + 1] <= lst[middle]) and (middle == 0 or lst[middle - 1] <= lst[middle]):return middle# If left neighbour is greater, then peak element is in the left halfelif (lst[middle - 1] > lst[middle]) and middle > 0:return find_peak_recursive(low, (middle - 1), lst)# If right neighbour is greater, then peak element is in the right halfelse:return find_peak_recursive((middle + 1), high, lst)def find_peak(lst):"""Finds a peak element:param lst: List of integers:return: Returns a peak element in a given list"""return lst[find_peak_recursive(0, len(lst) - 1, lst)]# Driver code to test above functionif __name__ == '__main__':# Example: 1lst = [7, 11, 22, 13, 4, 0]print('One peak point is: ', find_peak(lst))# Example: 2lst = [0, 3, 100, 2, -1, 0]print('One peak point is: ', find_peak(lst))# Example: 3lst = [6, 5, 4, 3, 2, 1]print('One peak point is: ', find_peak(lst))
Explanation
Start with the middle element of the list Line 11
- Compare the element with its neighbors
- If the middle element is not smaller than any of its neighbors, we return it Line 14
- If the middle element is smaller than its left neighbor, there is always a peak in the left half Line 18
- If the middle element is smaller than its right neighbor, there is always a peak in the right half Line 23