我正在尝试解决这个问题:
https://www.spoj.pl/problems/CERC07S/
我已经确定我需要一种数据结构,其中反转操作的时间复杂度较低。我尝试使用双向链表创建一个,其中(我认为)可以在O(1)中通过仅改变与起始和结束节点相关联的值来完成反转,该值指示遍历列表的方向。我试图实现它,但卡住了。也许这种方法是错误的!
树木适用于此吗?如果有,怎么样?是否赞赏任何想法或链接?
提前致谢。
答案 0 :(得分:1)
伪装成Selection sort。你使用双向链表来反转O(1)是正确的。 (不要混淆列表进入另一个列表。您可以删除要反转,反转和重新插入的子列表,所有这些都在O(1)中,或者任何使您的代码更简单的。)
我知道这只是一个练习,但是人们可以注意到逆转并不重要,重要的是交换第一个和最后一个元素。这就是维持不变at step i, the list up to position i is sorted
所需的全部内容。对于较大的i,列表包含未定义的顺序。如果您反转未定义的订单,您所拥有的所有订单仍然是未定义的订单:)
答案 1 :(得分:1)
Dimitris对这个算法到底是什么是正确的。也就是说,考虑到问题确实需要你执行逆转,双向链表是合适的。而你在O(1)中的逆转是正确的。可能让你陷入困境的是这部分:
[我认为]只需改变与起始节点和结束节点相关的值,就可以在O(1)中完成反转......
诀窍不是专门对节点做任何事情,而是对列表本身(即封装列表结构的对象)做任何事情;更改其状态以便迭代,它从 last 节点开始并从那里向后移动。如果要维护列表的可变性(在此示例中不相关),您还要使此状态负责确保先前声称将节点添加到列表的 end 的方法将它们添加到“开始”(新结束),反之亦然。直观地说,这个“状态”实际上只是一个简单的二进制开关,表明列表是否被反转。
答案 2 :(得分:1)
我同意双重链接列表。这是实现它的一种方法。
对于每个节点,将两个指针作为数组。同样在节点中有数字的值和布尔变量dir。最初,将每个节点中的第一个指针指向上一个节点,将第二个指针指向下一个节点,并将所有节点的dir设置为0.当您遍历链接列表时,跟踪具有方向的变量D首先将其设置为1。它指示要跟随哪个指针到达每个节点的下一个元素。到达节点时,如果dir设置为1,则将D设置为D的NOT,并继续使用D查找下一个节点。
要反转节点序列,请将dir设置为最后一个节点中的dir的NOT,并将节点序列的最后一个节点之后的节点设置为要反转的节点,将节点前面的节点的正确指针指向序列的最后一个元素(反之亦然),并将序列的正确指针指向序列的第一个元素(反之亦然)。
希望这能让您了解至少一种前进的方法。