To find the maximum height of the lakes that could potentially form, you need to find all the peaks or points that are higher than the points around them. By changing the code a bit, we can easily get peaks in one iteration:
lst = [0] + lst + [0] # Add zeros to either side to avoid having to deal with boundary issues peaks = [] for x in range(1, len(lst)-1): if lst[x-1] =< lst[x] >= lst[x+1]: # "x =< y >= z" is the same as "x =< y and y >= z" peaks.append(lst[x])
For your example, 4 3 7 1 3 2 3 5 6 2 1 3 3 2 3 peaks will be
[4, 7, 3, 6, 3, 3, 3]
Now we need to unite the lakes. The way we find which lakes can be combined is to go through the list of peaks, tracking the highest peak so far, and for each peak we delete any previous peaks that are lower than it and the highest peak so far. However, this does not require any additional information, so we can do this in the same for loop as the one that finds the peaks in the first place:
highest_so_far = 0 for x in range(1, len(lst)-1): if lst[x-1] =< lst[x] >= lst[x+1]: # "x =< y >= z" is the same as "x =< y and y >= z" while peaks and highest_so_far > peaks[-1] < lst[x]: peaks.pop() if lst[x] > highest_so_far: highest_so_far = lst[x] peaks.append(lst[x])
This will reduce the peaks in our example to
[4, 7, 6, 3, 3, 3]
Now, to find all the lakes, we simply look through the list and display the bottom of each pair. However, there is a wrinkle - with a series of 3, how do we know if it is flat or a lake that separates peaks of equal height? We need to know if the dots are next to each other or not. This can be done by including location information along with each peak -
peaks.append((lst[x], x))
Then, when we go through the final list of peaks, we check the bottom of the two, and if they are equal, we check whether they are next to each other (without them there is no lake).
Just so that I do not write all the code for you, I will leave it to you to change the cycle for working with peaks containing tuples and write a cycle that identifies lakes based on the peaks found.
Regarding time complexity, I believe this is done in linear time. Obviously, we look at the list only once, but in the middle there is a while . At each iteration, the while loop checks at least one peak, but if it ever checks more than one peak, this is because at least one peak has been deleted. Thus, outside the check for one iteration, not a single peak will be checked several times, which gives a no more linear increase in time.