我决定用一些假设/更改来检查这个问题,因为它让我觉得它成为一个更有趣的问题:
1)您可以从堆的任何部分向左或向右移动元素。
2)你可以将一个元素堆叠成一堆,无论它是更大、更小还是相同的大小。
3)只要您在较小的数字之前从未遇到过较大的数字,无论您如何通过堆栈,该数组都被视为已排序。所以 _ 11 2 3 已排序,但 _ _ 12 3 不是因为您可以将 2 解释为在 1 之前。
这导致了一个非常有趣的问题,尽管有这个公理:
公理A:你下棋的顺序无关紧要,可以以任何方式重新安排,以仍然达到相同的最终结果。
公理 Ab:如果数组中没有重复,则只需将每个元素移向其最终位置。
特别是,我制定了一个策略,希望您可以仅通过局部检查而无需递归/回溯来解决它,但我已经证明这是没有结果的,稍后会展示它。
我的策略是:
1) 从左到右继续寻找以错误方式翻转的对(在较低数字之前的较大数字)。
2a) 当你找到一个时,如果有一个空白点或堆栈,右手值可以立即填充,将它向左移动直到它填充它。
2b) 否则,将左值右移一位。这会造成您有一堆无关紧要的数字的情况 - 首先,在向下比较之前,根据 1) 的逻辑将您向右移动的值与其新右侧的值进行比较。
2bii) 以与对比较相同的方式处理向下比较 - 如果它可以适合空点或堆栈,则将较低的值向左移动,否则将较高的值向右移动并继续。
例子:
1231 -> 我们将 1b 向左移动,因为它可以放入堆栈。11 2 3 _
1321 -> 我们将 3 向右移动,因为 2 不适合空位/堆栈。我们将 1b 向左移动两次,因为它将适合一个空点/适合堆栈,然后我们将 3 向右移动,因为 2 将不适合一个空点/堆栈。1 1 2 3
1132 -> 我们将 3 向右移动,因为 2 不能向左移动。我们将 2 向左移动,因为它将适合一个空的位置。1 1 2 3
2311 -> 我们将 3 向右移动,因为 1a 不能向左移动。我们将 1b 向左移动两次,因为它将适合一个空白点。我们将 1a 向左移动,因为它会堆叠。我们向右移动 2,因为 1a1b 不能向左移动。我们将 1a2b 向左移动,因为它将填充一个空白点。11 2 3 _
但是,我们遇到了这两个起始数组的问题:
23411 10 步最佳,2r 3r 4r 1al*3 1bl*4 使 11 2 3 4 _。
23111 9 招最优,2r*3 3r*3 1bl 1cl*2 使_ _ 111 2 3 - 与23411 策略相反!我们少移动 1,多移动 23,因为有更多的 1,所以我们尽可能少地移动它们。
这表明我们不能只做一个简单的局部比较来解决这个新问题。
我还在思考这个问题,它看起来很有趣,而且我希望你们中的一些人喜欢和我一起思考这个问题:)