Reputation: 249
I have been given this problem to solve:
Suppose you're given a doubly-linked list and a pointer to some element of that list. Let's suppose that you want to search the list for some value v, which you know exists somewhere. Using no pointers except p, design an Θ(m)-time algorithm for finding v, where m is the distance between p and the node containing v. Do not modify the input list.
Does anyone have any ideas how to solve this? The only way I can think of doing this destructively modifies the list.
Upvotes: 4
Views: 540
Reputation: 55619
I think templatetypedef has the correct answer, but the below solution came to mind, based on the original phrasing of the question, which states that the list can't be "destroyed or shuffled", which might imply that modifying it is okay if you can change it back again - even if this is not true, I still think this is an interesting approach.
It can easily be solved with 2 pointers, right? One to go forward and one to go back, moving both at the same time until you the value you're looking for.
Now this is all well and good, except that we're only allowed to have 1 pointer.
If you think about a double linked-list, we know that the previous node's next
pointer is just a pointer to the current element, so, if we were to lose it, we could just set it up again.
So we could use p.prev.next
as free storage (and p.prev.prev.next
, given a similar argument).
So, we could only use one pointer going forward, and store the one going back in p.prev.next
, moving it appropriately as we go along.
Some Java-esque pseudo-code ignoring end-of-list checks and not finding it for simplicity (I think it's already complicated enough):
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
Upvotes: 4
Reputation: 372992
As a hint: What happens if you take one step forward, two steps back, four steps forward, eight steps back, etc.? How many total steps will it take to find the element?
When doing the analysis, you might find it useful to sum up a geometric series. If it helps, 1 + r + r2 + r3 + ... + rn-1 = (rn - 1) / (r - 1).
Hope this helps!
Upvotes: 5