A simple but extremely inefficient approach could be to just bruteforce each permutation in \( O(N!) \).
A better approach could be to order the input data by heights in ascending order:
we can position the smallest element first since there are no smaller elements in
the set that could be in front of it.
So we first can position the element 1 with 4 people in front of him
{ _ , _ , _ , _ , 1 , _ , _}
The second smallest element comes next: there’s one element in front of it and
since we already positioned 1, no smaller elements will move it further behind
{ _ , 2 , _ , _ , 1 , _ , _}
and so on.
The problem with this approach is that sorting requires \( O(N \log(N)) \) and
counting each time the free spaces from the beginning of the result vector makes
the overall complexity \( O(N^2) \).
Segment trees
A segment tree is a data structure
built as a full tree (a tree in which every node has either 0 or 2 children).
Since the height of a binary tree is \( h = \lceil \log_2(N) \rceil \), the maximum
number of nodes a full tree can be \( max = 2(2^h) -1 \).
The structure stores the results of an interval predicate in a heap-indexed-like vector.
For a simple sum predicate (i.e. we’re interested in the sum of a given range of
elements of the input set) we can build a segment tree in \( O(N) \) and query
the value of the predicate in a given interval \( [x;y] \) in \( O(\log(N)) \).
Updating is also \( O(\log(N)) \).
Given these tools the algorithm becomes pretty straightforward