我已经解决了这个问题:
假设您有一个双向链表和一个指向该列表中某个元素的指针。假设你想要在列表中搜索某个值v,你知道它存在于某个地方。除了p之外不使用指针,设计用于查找v的Θ(m)-time算法,其中m是p与包含v的节点之间的距离。不要修改输入列表。
有没有人有任何想法如何解决这个问题?我能想到的唯一方法是破坏性地修改列表。
答案 0 :(得分:5)
作为提示:如果向前迈出一步,向后退两步,向前退步四步,退回八步等,会发生什么?找到元素需要多少步骤?
进行分析时,您可能会发现总结几何系列很有用。如果有帮助,1 + r + r 2 + r 3 + ... + r n-1 =(r n - 1)/(r - 1)。
希望这有帮助!
答案 1 :(得分:4)
我认为templatetypedef has the correct answer,但根据问题的原始措辞,我想到了以下解决方案,该问题表明该列表无法被销毁或改组#34;这可能意味着修改它是可以的,如果你可以再次改变它 - 即使这不是真的,我仍然认为这是一个有趣的方法。
可以用2个指针轻松解决,对吗?一个前进,一个返回,同时移动两个,直到你找到你想要的价值。
现在这一切都很好,除了我们只允许有1个指针。
如果考虑双链表,我们知道前一个节点的next
指针只是指向当前元素的指针,所以,如果我们丢失它,我们就可以再次设置它。
所以我们可以使用p.prev.next
作为免费存储空间(和p.prev.prev.next
一样,给出类似的参数)。
所以,我们只能使用一个指针前进,然后将一个指针存储在p.prev.next
中,并在我们进行时适当地移动它。
一些Java-esque伪代码忽略了列表末尾检查而没有简单地找到它(我认为它已经足够复杂了):
if p.data == v
return v
p = p.next
p.prev.next = p.prev.prev
while not found
if p == v || p.prev.next == v
p.prev.next = p // restore p.prev.next
return v
p = p.next
p.prev.next = p.prev.prev.next.prev // set up p.prev.next from p.prev.prev.next
p.prev.prev.next = p.prev // restore p.prev.prev.next