我有关于算法的一个与语言无关的问题。
这来自于我看到的一个(可能很简单的)编程挑战,但是我太傻了无法解决它,但又好奇心足以让我困扰。
目标是通过交换列表中数字的位置将整数列表排序为升序。每次交换两个数字时,您必须将它们的和添加到运行总额中。挑战在于产生具有最小可能运行总额的排序列表。
示例:
3 2 1 - 4
1 8 9 7 6 - 41
8 4 5 3 2 7 - 34
虽然你可以直接给出答案,但如果可能的话,你更愿意提供正确方向上的“提示”,我更喜欢这样。
我有关于算法的一个与语言无关的问题。
这来自于我看到的一个(可能很简单的)编程挑战,但是我太傻了无法解决它,但又好奇心足以让我困扰。
目标是通过交换列表中数字的位置将整数列表排序为升序。每次交换两个数字时,您必须将它们的和添加到运行总额中。挑战在于产生具有最小可能运行总额的排序列表。
示例:
3 2 1 - 4
1 8 9 7 6 - 41
8 4 5 3 2 7 - 34
虽然你可以直接给出答案,但如果可能的话,你更愿意提供正确方向上的“提示”,我更喜欢这样。
我手动尝试解决了其中一个示例:
由于您需要移动数字1,因此似乎必须对问题进行详尽的搜索才能完成 - 其中的细节已经被另一位用户发布。请注意,在使用此方法时,如果数据集很大,则可能会遇到问题。
如果问题允许“接近”答案,那么您可以简单地制作一个贪心算法,将最大的项目放入位置 - 直接这样做,或者首先将最小元素交换到该插槽中。
比较和遍历显然是免费的,您可以预先计算数字必须移动的“距离”(实际上是最终排序顺序)。难题是交换算法。
尽可能减少总体交换很明显很重要。还要尽可能减少较大数字的交换。
我相信通过以无状态方式评估每个排序无法保证最优的交换过程,尽管您可能经常接近(这不是挑战)。
我认为这个问题没有简单的解决方案,我的方法可能不比优先队列的方法更好。
找到最小的数字N。 除了N之外,任何占据彼此所需位置的数字对都应该交换。 通过蛮力法组装每一组可以相互交换到其所需位置的数字集合,使得在集合内排序的成本小于用N交换集合中每个元素的成本。 这些集合将包含若干个循环。在这些循环内进行交换,以便最小的数字被交换两次。 使用N作为占位符,交换包括N在内的所有剩余数字,这些数字构成一个循环。
您所需支付的费用是根据交换次数而不是比较次数计算的。而且您也没有提到保持其他记录需要支付费用。