美文网首页
Leetcode-142Linked List Cycle II

Leetcode-142Linked List Cycle II

作者: LdpcII | 来源:发表于2018-03-21 14:03 被阅读0次

    142. Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

    Note: Do not modify the linked list.

    Follow up:
    Can you solve it without using extra space?

    题解:

    本题要求的是链表中存在的环的入口节点,如果不存在环,则返回NULL;
    两种方法:
    第一种方法很简单,使用集合set,每次在set中查找节点是否已存在,如果没有,将链表中节点存入set中,如果存在,则说明该位置为环的起始节点;
    下面我们详细介绍下第二种方法,快慢指针;


    image.png

    如图:我们用fast表示快指针,每次移动两步;slow表示慢指针,每次移动一步;图中f1,s1分别对应着第一次移动是快慢指针移动后所指向的位置;可以看到,当快慢指针移动到第五步(f5,s5)时,他们相遇了;下面我们来分析下快慢指针相遇前经过的节点:
    slow:节点1->2->3->4->5->6
    fast:节点1->2->3->4->5->6->7->3->4->5->6
    由于slow每次移动一步,fast每次移动两步,所以不难得出:
    fast = 2*slow
    所以得到:
    (1->2->3->4->5->)6, 1->2->3(->4->5->6) =
    (1->2->3->4->5->)6->7->3(->4->5->6)
    删除带括号的重复部分,最终得到:
    1->2->3 = 6->7->3
    进行到这里,我们可以得出介样一个结论,辣就是从头结点(1)到环的起始节点(3)的距离等同于从快慢指针相遇的结点(6)到环的起始节点(3)的距离!!
    最后给出快慢指针的C++实现以及set的Python实现:

    My Solution1(C/C++完整实现):

    #include <cstdio>
    #include <iostream>
    
    using namespace std;
    
    struct ListNode {
        int val;
        ListNode *next;
        ListNode(int x): val(x), next(NULL) {}
    };
    
    class Solution {
    public:
        ListNode *detectCycle(ListNode *head) {
            ListNode *slow = head;
            ListNode *fast = head;
            ListNode *meet = NULL;
            while(fast) {
                slow = slow->next;
                fast = fast->next;
                if(!fast) {
                    return NULL;
                }
                fast = fast->next;
                if(fast == slow) {
                    meet = fast;
                    break;
                }
            }
            while(meet) {
                if(head == meet) {
                    return head;
                }
                meet = meet->next;
                head = head->next;
            }
            return NULL;
        }
    };
    
    int main() {
        ListNode a(1);
        ListNode b(2);
        ListNode c(3);
        ListNode d(4);
        ListNode e(5);
        ListNode f(6);
        ListNode g(7);
        a.next = &b;
        b.next = &c;
        c.next = &d;
        d.next = &e;
        e.next = &f;
        f.next = &g;
        g.next = &c;
        Solution s;
        ListNode *result = s.detectCycle(&a);
        printf("%d\n", result->val);
        return 0;
    }
    

    结果:

    3
    
    Process returned 0 (0x0)   execution time : 0.023 s
    Press any key to continue.
    
    

    My Solution2(Python):

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def detectCycle(self, head):
            """
            :type head: ListNode
            :rtype: ListNode
            """
            s = set('')
            while head:
                if head not in s:
                    s.add(head)
                else:
                    return head
                head = head.next
            return None
    

    相关文章

      网友评论

          本文标题:Leetcode-142Linked List Cycle II

          本文链接:https://www.haomeiwen.com/subject/gapqqftx.html