Prove the time complexity of this algorithm of finding longest subarray with maximum value in the middle I'm trying to find time complexity $T(n)$ of the algorithm by a given pseudocode:

1: for i:=1 to N do
2: begin
3:   len := 1
4:   while i - len &gt;= 1 and i + len &lt;= N do
5:   begin
6:     if a[i] &gt; a[i - len] and a[i] &gt; a[i + len] then
7:       len := len + 1
8:     else
9:       break
10:   end
11:   print(i, len)
12: end


I know that the answer is $T(n) = O(n\log n)$ but I struggle to prove that.

From the pseudocode its clear that this algorithm is designed to find the longest subarray with each element smaller then the middle one. (actually this algorithm prints the length of such array for each array element)

I can't prove it formally because I struggle with the content-dependent loop at 5-10, but informally I went like this:
Lets construct the array which will be the worst case for this algorithm.

For the sake of simplicity lets use array with 15 elements and start with array filled with zeros:
$$0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0$$
external loop will execute 15 times and each time the loop 5-10 will perform a single comparison
Now we will do the following: we divide array in two and put maximum value in the middle. Then for each half we will do the same, except the value will be decresed by 1.

We will get the following array:
$$0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0$$

Now, intuitively I can see why this is the worst case for the algorithm and where $logn$ comes from, but I can't prove it properly.

As a side note I would appreciate any pointers toward where one can practice these kind of problems (concrete algorithms time complexity analysis, preferably with answers/explanations)
Let an array $a[1],\ldots,a[n]$ be given. For an index $i$, let $\ell(i)$ be the largest $\ell$ such that $\{i-\ell,\ldots,i+\ell\} \subseteq \{1,\ldots,n\}$ and $a[i]$ is larger than all elements $a[i-\ell],\ldots,a[i-1],a[i+1],a[i+\ell]$. It is not difficult to see that the running time of the algorithm on the array is $\Theta(n + \sum_{i=1}^n \ell(i))$.

This prompts the following definition:


  Given $n$, the quantity $M(n)$ is the maximum of $\sum_{i=1}^n \ell(i)$ over all arrays of length $n$.


Let $a$ be an array for which $M(n)$ is achieved, and let $a[i]$ be an element of maximum value. Then $\ell(i) = \min(i-1,n-i)$. Moreover, since $a[i]$ is not smaller than any other element, we have $\sum_{j=1}^{i-1} \ell(j) \leq M(i-1)$ and $\sum_{j=i+1}^n \ell(j) \leq M(n-i)$. This shows that
$$
M(n) \leq \max_{i=1}^n M(i-1) + M(n-i) + \min(i-1,n-i).
$$
In fact it is not hard to check that equality holds: take the maximum $i$, and combine two arrays attaining $M(i-1)$ and $M(n-i)$ with a larger element in the middle. This gives the recurrence
$$
M(0)=0, \; M(n) = \max_{i=1}^n [M(i-1) + M(n-i) + \min(i-1,n-i)].
$$
This recurrence is A078903. It is intuitively clear that the best choice for $i$ is $\lfloor \frac{n+1}{2} \rfloor$ or $\lceil \frac{n+1}{2} \rceil$.

We can solve the recurrence explicitly: for $0 \leq k &lt; 2^m$, we have
$$
M(2^m+k) = (m-2)2^{m-1}+1+N_2(k),
$$
where $N_2(k)$ is the total number of 1s in the binary expansions of $1,\ldots,k$ (this is A000788). It is known that $N_2(k) = k\log_2 k + O(k)$, and so $M(n) = \Theta(n\log n)$. This asymptotic estimate also follows from the monotonicity of $M(n)$, by considering the cases $k = 0$.

We conclude that the running time of the algorithm is indeed $O(n\log n)$, and moreover this estimate is tight.