重排数组的算法

时间:2015-05-29 10:58:08

标签: arrays algorithm

我有一个数组:

1 1A 2 2A 3 3A 4 4A 5 5A

我需要随机重新排列它,条件是:1A必须落后1,2A落后于2 ......(不一定喜欢1 1A)

重新排列后的预期结果如下:

1 4 2 4A 3 2A 5 1A 5A 3A

帮助我获得最佳算法(最佳速度)

2 个答案:

答案 0 :(得分:5)

你可以尝试这样:

  • 将元素分组到不同的队列中,使得具有某些“顺序”的所有元素都在同一队列中,例如[[1, 1A], [2, 2A, 2B], [3, 3A], ...]
  • 随机选择其中一个队列,删除第一个元素并将其添加到结果中
  • 重复,直到所有队列都为空

如果部分排序更复杂,例如如果某个元素a必须在bc之前,但bc之间没有部分排序,那么您可能会对树或类似的。

另外,正如@vib所指出的,为了确保结果中元素的均匀分布,你应该选择不同的队列,其概率与该队列中剩余的元素数量成正比。

答案 1 :(得分:2)

  • 随机播放阵列(Fisher yates shuffle
  • 对于每个x,xA对 - 如果x在xA之后,则切换它们。这可以通过在map:Element->Index中为数组中的所有元素创建O(n)来完成。

总复杂度:O(n)(时间)平均情况
保证随着渔民的正确性,输出随机均匀地改变。

的伪代码:

array = shuffle(array)
map = new map
for each element e in array with index i:
    map.add(e,i)
for each element e in the array:
   if e is "x" (not "xA"):
       i = map.get(e)
       j = map.get(xA)
       if j<i:
         swap(arr,i,j)
  • 如果只有2个(x,xA,xB,...) - 你可以列出它们并以类似的方式在主循环中排序。