【发布时间】:2011-09-27 10:58:42
【问题描述】:
修复正整数n 和k。
让A 是一个长度为n 的数组,A[i] 是一个长度为k 的数组,其中每个条目都是n-i。例如,n=5 和 k=1,这只是
[ [5] , [4] , [3] , [2] , [1] ]
对于n=5 和k=2,这是
[ [5,5] , [4,4] , [3,3] , [2,2] , [1,1] ]
目标是通过交换相邻数组中的数字(例如交换A[i][j1] 和A[i+1][j2])对这个数组数组进行冒泡排序,直到A[i] 的每个条目对于每个i 都是i+1。
问题是:需要多少次交换以及什么是最佳算法?
注意: 有很多很多更好的排序算法可供使用。但是,对于这个问题,我只对应用上述冒泡排序感兴趣。我只能交换来自相邻数组的条目,并且我只对必要的最小交换次数感兴趣。我非常感谢其他排序算法的所有建议,但这是我试图理解的问题。
示例:
对于k=1,这是众所周知的。交换次数是A 的反转数,被视为一个排列,因此最小交换次数是二项式系数(n choose 2) = n(n-1)/2,这可以通过交换任何乱序对来获得:A[i] > A[j]。对于第一个示例,这是一个最佳冒泡排序:
[ [5] , [4] , [3] , [2] , [1] ]
[ [4] , [5] , [3] , [2] , [1] ]
[ [4] , [5] , [2] , [3] , [1] ]
[ [4] , [2] , [5] , [3] , [1] ]
[ [4] , [2] , [5] , [1] , [3] ]
[ [4] , [2] , [1] , [5] , [3] ]
[ [4] , [1] , [2] , [5] , [3] ]
[ [1] , [4] , [2] , [5] , [3] ]
[ [1] , [4] , [2] , [3] , [5] ]
[ [1] , [2] , [4] , [3] , [5] ]
[ [1] , [2] , [3] , [4] , [5] ]
对于k=2,使用相同的策略将给出2 (n choose 2) 需要交换的界限。对于上面的示例,这意味着 20 交换。但是有一个解决方案只使用15交换:
[ [5,5] , [4,4] , [3,3] , [2,2] , [1,1] ]
[ [5,4] , [5,4] , [3,3] , [2,2] , [1,1] ]
[ [5,4] , [3,4] , [5,3] , [2,2] , [1,1] ]
[ [5,4] , [3,4] , [2,3] , [5,2] , [1,1] ]
[ [5,4] , [3,4] , [2,3] , [1,2] , [5,1] ]
[ [5,4] , [3,4] , [2,1] , [3,2] , [5,1] ]
[ [5,4] , [3,1] , [2,4] , [3,2] , [5,1] ]
[ [1,4] , [3,5] , [2,4] , [3,2] , [5,1] ]
[ [1,4] , [3,2] , [5,4] , [3,2] , [5,1] ]
[ [1,4] , [3,2] , [2,4] , [3,5] , [5,1] ]
[ [1,4] , [3,2] , [2,4] , [3,1] , [5,5] ]
[ [1,4] , [3,2] , [2,1] , [3,4] , [5,5] ]
[ [1,4] , [1,2] , [2,3] , [3,4] , [5,5] ]
[ [1,1] , [4,2] , [2,3] , [3,4] , [5,5] ]
[ [1,1] , [2,2] , [4,3] , [3,4] , [5,5] ]
[ [1,1] , [2,2] , [3,3] , [4,4] , [5,5] ]
此解决方案最适合n=5 和k=2(通过蛮力证明找到所有解决方案)。对于n=6,最佳解决方案采用22 交换,但该解决方案看起来不如n=5 的解决方案好(按照右5,然后是左1,然后是右5,等等),所以我仍然不知道最佳策略,更不用说公式或更好的交换次数界限。
我已经考虑了几天了,但没有提出任何启发性的想法。如果有人对此问题有任何想法,请分享。我会很高兴知道更多关于k=2 案例的信息。对于一般情况下的任何想法都更好。
编辑:如果我不能按照您的喜好激发这个问题,我深表歉意,但这里有一个尝试:对排列进行排序所需的冒泡排序数是组合学和数论中非常重要的统计数据,称为排列的反转数.您可以使用更好的算法对无序排列进行排序,但这是为您提供代数含义的算法。如果这没有帮助,也许这个相关的 SO 帖子可能:What is a bubble sort good for?
更新:oldest answer below 给出了交换次数的下限(和上限)。 second oldest answer 给出了一个非常接近这个下限的算法(经常达到它)。如果有人可以改进界限,或者更好地证明下面给出的算法是最优的,那就太棒了。
【问题讨论】:
-
我不明白。根据您的描述,
k=1的结果应该是[ [1], [2], [3], [4], [5] ],您可以在 2 次交换中获得,而不是 10 次。我哪里错了? -
@svick:我很抱歉。我隐含地假设您只能交换相邻数组中的条目。我现在已经在问题中明确提出了这个假设。感谢您指出我的疏忽。
-
您只关心交换次数(性能问题)还是比较次数?
-
@Yochai:我根本不在乎比较。我被允许做的唯一操作是相邻数组条目之间的交换,我想最小化这些。
-
所以你可以在开始交换之前进行任意数量的比较?
标签: algorithm sorting multidimensional-array bubble-sort