又是另一个不必要的答案!这个答案明确保留了排列数组
P
,这对我的情况是必要的,但代价较高。此外,这种方法不需要跟踪正确放置的元素。我知道之前的答案提供了
O(N)
解决方案,所以我想这只是为了娱乐!
我们得到最好情况复杂度为
O(N)
,最坏情况下为
O(N^2)
,平均情况下为
O(NlogN)
。对于大型数组 (
N~10000
或更大),平均情况基本上等于
O(N)
。
以下是 Java 的核心算法(我是说伪代码 *咳咳*):
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;
}
下面是算法的一个运行示例(类似于之前的答案):
假设有A = [a, b, c, d, e]
并且P = [2, 4, 3, 0, 1]
那么预期结果为[ c, e, d, a, b ]
i=0: [a, b, c, d, e]
^ ^
i=1: [c, b, a, d, e]
^ ^
i=2: [c, e, a, d, b]
^ ^
i=3a: [c, e, d, a, b]
^
i=3b: [c, e, d, a, b]
? ^
i=3c: [c, e, d, a, b]
? ^
i=3d: [c, e, d, a, b]
^
done.
这个算法可以在
while
循环中跳来跳去,直到任何索引
j<i
,在第
ith次迭代期间最多可以反弹
次。最坏情况下(我认为!)每次外层的for
循环迭代都会导致来自while
循环的个额外赋值,因此我们将得到一个算术级数的形式,这将为复杂度增加一个N^2
的因素!然而,运行这个算法的一系列N
并平均计算while
循环所需的“额外”赋值数(在每个N
的多个排列上进行平均),强烈提示我平均情况下的时间复杂度是O(NlogN)
。
谢谢!
O(n)
的空间,这不是常数。 - Patrick Kostjens