Yet another unnecessary answer! This one preserves the permutation array P
explicitly, which was necessary for my situation, but sacrifices in cost. Also this does not require tracking the correctly placed elements. I understand that a previous answer provides the O(N)
solution, so I guess this one is just for amusement!
We get best case complexity O(N)
, worst case O(N^2)
, and average case O(NlogN)
. For large arrays (N~10000
or greater), the average case is essentially O(N)
.
Here is the core algorithm in Java (I mean pseudo-code *cough cough*)
int ind=0;
float temp=0;
for(int i=0; i<(n-1); i++){
// get next index
ind = P[i];
while(ind<i)
ind = P[ind];
// swap elements in array
temp = A[i];
A[i] = A[ind];
A[ind] = temp;
}
Here is an example of the algorithm running (similar to previous answers):
let A = [a, b, c, d, e]
and P = [2, 4, 3, 0, 1]
then expected = [c, e, d, a, b]
i=0: [a, b, c, d, e] // (ind=P[0]=2)>=0 no while loop, swap A[0]<->A[2]
^ ^
i=1: [c, b, a, d, e] // (ind=P[1]=4)>=1 no while loop, swap A[1]<->A[4]
^ ^
i=2: [c, e, a, d, b] // (ind=P[2]=3)>=2 no while loop, swap A[2]<->A[3]
^ ^
i=3a: [c, e, d, a, b] // (ind=P[3]=0)<3 uh-oh! enter while loop...
^
i=3b: [c, e, d, a, b] // loop iteration: ind<-P[0]. now have (ind=2)<3
? ^
i=3c: [c, e, d, a, b] // loop iteration: ind<-P[2]. now have (ind=3)>=3
? ^
i=3d: [c, e, d, a, b] // good index found. Swap A[3]<->A[3]
^
done.
This algorithm can bounce around in that while
loop for any indices j<i
, up to at most i
times during the ith
iteration. In the worst case (I think!) each iteration of the outer for
loop would result in i
extra assignments from the while
loop, so we'd have an arithmetic series thing going on, which would add an N^2
factor to the complexity! Running this for a range of N
and averaging the number of 'extra' assignments needed by the while
loop (averaged over many permutations for each N
, that is), though, strongly suggests to me that the average case is O(NlogN)
.
Thanks!