Write an efficient algorithm to perform arbitrary vector rotations. Time complexity should be \( O(N) \)
Solution I
Trivial solution: use an auxiliary vector to rotate the vector by \( k \) positions
Time \( O(N) \), space \( O(N) \); it doesn’t work with negative \( k \) values.
Solution II
A better space-efficient algorithm to perform a vector rotation relies on three subvector inversions. Let’s suppose we have a vector \( v \), begin and end positions \( [i,j[ \) and a split point \( s \).
We can construct the output vector \( v’ \) as follows
\[v' = \phi( \phi(v_{i,s}), \phi(v_{s,j}) )\]
where \( \phi(x) \) is the reverse function.
The algorithm runs in \( O(N) \) and \( O(1) \) space.
Solution III
A third more complex approach which often exhibits better data locality is now presented. The key to understanding it is considering three separate cases:
\( s = \frac{j - i}{2} \)
begin = 0
n_begin = split
for i = 0 to split
swap(begin, n_begin)
begin++
n_begin++
\( s > \frac{j - i}{2} \)
begin = 0
n_begin = split
for i = 0 to dist(sj)
swap(begin, n_begin)
begin++
n_begin++
n_begin = split // Reset exhausted list
// Repeat the process until case 3 applies
\( s < \frac{j - i}{2} \)
begin = 0
n_begin = split
for i = 0 to dist(is)
swap(begin, n_begin)
begin++
n_begin++
split = n_begin
// We now have a subinstance of the original problem
Algorithm is \( O(N) \).
A driver stub is also provided for completeness’ sake