Chapter 2 Linked Lists - 2.5

Problem 2.5: Given a circular linked list, implment an algorithm which returns node at the beginning of the loop.
DEFINITION
Circular linked list: A (corrupt) linked list in which a node's next pointer points to an earlier node, so as to make a loop in the linked list.
EXAMPLE
input: A->B->C->D->E->C[the same C as earlier]
output: C


The only solution I can come up with is the most intuitive one, marking visited node with a hash table.
class node:
    def __init__(self, data=None):
        self.data = data
        self.next = None

def find_beginning(head):
    hash_table = {}
    while head != None:
        if hash_table.has_key(head.data):
            return head
        else:
            hash_table[head.data] = 1
        head = head.next
    return False

if __name__ == "__main__":
    n1 = node(1)
    n2 = node(2)
    n3 = node(3)
    n4 = node(4)
    n5 = node(5)
    n1.next = n2
    n2.next = n3
    n3.next = n4
    n4.next = n5
    n5.next = n3
    print find_beginning(n1).data

However, when I turned to the answer page, I found a solution which is so tricky that it takes several minutes to understand:
def find_beginning(head):
    p1 = head.next
    p2 = head.next.next
    while p1.data != p2.data:
        p1 = p1.next
        p2 = p2.next.next
    p3 = head
    while p1.data != p3.data:
        p1 = p1.next
        p3 = p3.next
    return p3

Let me explain the code above in detail:
First of all, there are two pointers pointing to the head of linked list. We move pointer p1 one step each time, while moving p2 two steps each time. Let the number of steps from head to the start of loop be k. Then, when p1 comes to the start of the loop in linked list, p2 is k (which is unknown) steps ahead in the loop.
Let the number of nodes in the loop is n. If we keep moving p1 by one step each time and moving p2 by two steps, it will take (n-k) steps before p2 meet p1. Now, let us calculate how many steps is needed to move p1 to the start of loop: it is n-(n-k)=k.
Although k is now known, we can measure it in another way: let a pointer p3 move by one step each time from the head of linked list, while moving p1 at the same speed. When p1 and p3 meet, they are at the start of loop.
What a tricky solution! I learned that we can not only use more than onepointers, but also moving different pointers at different speed.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值