仅使用swap来变换数组顺序

时间:2012-08-13 07:08:10

标签: arrays algorithm sorting

假设你有两个数组,a和b。 a的数据完全隐藏起来。您可以在a上执行的唯一操作是交换两个元素。 b的数据完全暴露且可变。

位置i处的b值表示存储在[i]中的值的目的地。也就是说,如果b [3] = 7,我们想要将[3]中的值移动到[7]中。我正在尝试编写一种算法,该算法根据数组b中的信息使用交换操作(最好是线性时间和常量空间)来改变数组a。仅作为一个例子:

if   a  = { a b c d e f }
and  b  = { 1 3 2 0 5 4 }
then a' = { d a c b f e }
(ie, a[i] = a'[b[i]])

我尝试了一种天真的方法来迭代b并快乐地做一个.Swap(i,b [i]),一直在吹口哨,但最终结束了自己写的并移动已经在右边的数据地方(正如你猜的那样)。

编辑:这实际上必须是线性时间。这是一个并行排序算法,所以速度是最重要的。

2 个答案:

答案 0 :(得分:1)

Go中的解决方案:

for i := 0; i != len(b); i++ {
    for b[i] != i {
        a.Swap(i, b[i])
        b.Swap(i, b[i])
    }
}

这可能不会立即看到O(n),但请注意

  • 每个a.Swap()将a的至少一个元素放入其最终位置
    • 一旦元素处于最终位置,它就永远不会被再次交换
    • 所以最多只有n个交换
  • b[i] != i测试每次交换一次,每次i一次
    • 所以最多有2n个测试

如您所见,该算法的时间为O(n),空间为O(1)。

答案 1 :(得分:0)

按升序排列b的元素,同时交换b的元素,同时交换它们。例如,使用冒泡排序:

for(int i=0;i<b.length;i++){
for(int j=0;j<b.length-i-1;j++){
if(b[j+1]<b[j]){
// swap b[j+1] and b[j]
// swap a[j] and a[j+1]
}
}
}