LeetCode刷题:Linked List Cycle 及其进阶Linked List Cycle II

来源:互联网 发布:部落冲突咏王升级数据 编辑:程序博客网 时间:2024/05/20 13:40

Given a linked list, determine if it has a cycle in it.

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

1. 首先解决的问题是 判断单链表 有没有环?

解题思路:

两个指针slow 和 fast,开始都指向 head, slow指针每次走一步,fast 指针每次走两步,看看最终 slow 和 fast 会不会重合,如果 链表有环,那么一定会重合。

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    bool hasCycle(ListNode *head)     {        if(head == NULL || head->next == NULL)        {            return false;        }                ListNode *slow, *fast;        slow = fast = head;                //fast = fast->next;                while( fast != NULL && fast->next != NULL)        {            fast = fast->next;            if (slow == fast)            {                return true;            }            slow = slow->next;            fast = fast->next;        }                        if(fast == NULL || fast->next == NULL)        {            return false;        }        else        {            return false;        }    }};

2. 问题进阶: 如果链表有环,返回环开始的那个节点, 该怎么做呢?

LeetCode 上的问题:

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?

引用网上的一张图:


image


Like the picture shows above: assume linked list has cycle,the length of cycle is Y,the length outside cycle is X. 

Two pointers, one goes one step per time, another goes two steps per time. If they went t times and meet at the K node.

ponter 1 每次走一步,pointer 2 每次走两步, 下面公式中的t 代表每个pointer总的路程:

for pointer 1: t = X+nY+K

for pointer 2: 2t = X+mY+K (m,n is unknown)

From above equation, we could get:

2X + 2nY + 2K = X + mY + K

=>   X+K  =  (m-2n)Y 


所以 X+K 等于 Y 的整数倍。

所以有下面的结论(数学问题,我还是不太能理解):

It is clear that the relationship between X and K is complementary based on Y. 

Which is to say, if pointer 1 goes X steps from start node and pointer 2 goes X steps form K node. They will meet at the start place of cycle. 

Complexity is O(n)

反正就是: pointer 1 和 pointer 2 找到重合点K 后,那么 pinter 1 返回起点head, pointer 2 从K处继续走,他们一定会在环的起始点相遇。

这个我试了几组,确实是这样的。


代码如下:


/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode *detectCycle(ListNode *head) {        //if(head == NULL || head->next == NULL)        //{        //    return NULL;        //}                ListNode *slow, *fast;        slow = fast = head;        //fast = fast->next;                while(fast!=NULL && fast->next !=NULL)        {            slow = slow->next;            fast = fast->next->next;            if(slow == fast)            {                break;            }            //fast = fast->next;        }                if (fast == NULL || fast->next == NULL)        {            return NULL;        }                //has cycles, so find the cycle start point.        slow = head;        if(slow->next == fast)        {            return slow;        }        while(slow != fast)        {            slow = slow->next;            fast = fast->next;        }        return slow;    }};



0 0
原创粉丝点击