如何找到最短的堆栈移动序列以获得目标堆栈?
Posted
技术标签:
【中文标题】如何找到最短的堆栈移动序列以获得目标堆栈?【英文标题】:How do I find the shortest sequence of stack moves to get the goal stack? 【发布时间】:2012-10-29 08:35:53 【问题描述】:我的任务是编写一些代码,找出将给定起始堆栈带到给定目标堆栈的最短移动序列。我得到了一个原始的书籍列表,描述了堆栈是如何开始的,还有一个书籍的目标列表,显示了我需要它们的目标顺序。问题在于标准排序算法不起作用,因为书籍是基于一个人的偏好,而不是任何特定的逻辑。
问题要你使用的系统如下:从书架的任何地方拉出一本书,一次一本书,然后放在书架的顶部。所以如果你有书 X、Y 和 Z,你可以选择取出 Y,按 Y、X、Z 的顺序排列。
首字母:
'1984 - George Orwell'
'Moby Dick - Herman Melville'
'To Kill A Mockingbird - Harper Lee'
'Atlas Shrugged - Ayn Rand'
'The Black Cat - Edgar Allen Poe'
目标:
'Atlas Shrugged - Ayn Rand'
'To Kill A Mockingbird - Harper Lee'
'1984 - George Orwell'
'Moby Dick - Herman Melville'
'The Black Cat - Edgar Allen Poe'
这是作业。但是,我并不是在寻找人来为我做这件事,因为这会破坏任务的目的。我只是在寻找一些开始的想法或提示,因为我不知道从哪里开始。
注意:我打算将此标记为作业,但标记明确表示不要,所以我没有。如有错误请指正。
【问题讨论】:
【参考方案1】:一个非常简单的算法是遍历堆栈,每次查找并取出属于底部的下一本书。对于小堆栈,线性搜索就足够了。
在您的示例中,您将在第一次迭代时取出 'The Black Cat - Edgar Allen Poe'
,在第二次迭代时取出 'Moby Dick - Herman Melville'
,在第三次迭代时取出 '1984 - George Orwell'
,以此类推。
这是一个 O(n^2) 算法。
【讨论】:
我对“大 O”表示法只有一点经验,所以你能解释一下为什么它是 O(n^2) 吗?顺便说一句,谢谢。 "找到 最短的移动序列" ...这不符合标准。它生成一个有效的移动序列,但不一定是最短的。 这不会找到最少的移动,但如果您查看我的 ABGFCED 示例,您将至少执行 5 个脉冲(如果您忽略 A 和 B),这只是一个可能的解决方案,这超过 3。 完全正确 - 无论如何,这都不是最佳解决方案。然而,这是一个可以使用的起点。 @trainreq:它对 n 本书中的每一本书进行 O(n) 比较,使其成为 O(n^2)。【参考方案2】:好的,主要问题是你只能放在上面,但你可以选择任何书。你想要的是提示,而不是方法,所以这里有一些:
-
因为你只能放在顶部,所以总是从最难到达的底部开始看
显然,您永远不需要将任何已经放在正确位置的书拉出来
您需要以正确的顺序拉出现在位于书上方的书下的所有书
如果您将书籍堆叠在顶部,则应按正确的顺序放在那里
要将 A B G F C E D 转换为字母顺序,最好先拉 E,然后是 F,然后是 G,如果始终附加到末尾。
我希望这能让你开始,我没有明确表示。
【讨论】:
感谢您的回答。你会让每本书都有自己的字符串变量,然后将这些变量压入堆栈,然后继续进行排序操作吗?或者你会使用另一种数据结构来收集书籍吗?希望这是有道理的。 我会将书籍保存为字符串数组/堆栈,并在尝试确定最佳移动顺序之前生成有序副本。 哦刚刚记得你在哪里给出了正确的顺序。否则排序将通过 sorted() 进行。所以你基本上开始比较初始和最终列表。在堆栈底部正确排序的书籍应该例如不可触碰 我不会撒谎,我还是很困惑。您是否将堆栈的内容复制到列表中以便可以迭代它们?我的问题是我的堆栈 ADT 不允许我“选择任何书”,我的意思是我不能访问堆栈的任意元素,因为我只有 peek、push、pop、isEmpty 和 size 方法。我希望这是有道理的,并为无知感到抱歉。我觉得这是一个愚蠢的问题。 我认为您应该将书库保存为数组或列表,因为您需要能够从任何地方拉一本书才能解决您的任务。你会在物理事物的命名和计算机事物的命名之间偶然发现一些其他的假朋友。以上是关于如何找到最短的堆栈移动序列以获得目标堆栈?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 php 数组中删除具有特定值的所有元素? (以尽可能最短的方式)[重复]
如何通过正确的 Crashlytics 错误分组获得更好的 RxJava 堆栈跟踪
如何在Dart中获取当前的堆栈跟踪以获得Completer.CompleteException(exception,stackTrace);