【LeetCode】Linked list Cycle

来源:互联网 发布:sql怎么导入数据 编辑:程序博客网 时间:2024/05/29 17:23

题目描述;

Linked List Cycle

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

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

如何判断一个单链表中有环?

Linked List Cycle II

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

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

如何找到环的第一个节点?

题目大致有这么几种解法:

1、最朴素的使用两个指针a和b,双重遍历,遇到a==b则存在环,复杂度为O(n^2)

2、使用HashSet,每遍历到一个节点就将节点放进HashSet中,再判断next是否在HashSet中,复杂度为O(n),当然做不到题目要求的“solve it without using extra space”。

3、“龟兔赛跑”法。先附图:

X为链表起点,Y为环的起点,Z为相遇点

两个指针fast,slow同时进行遍历操作,假设fast遍历的步长(即速度)为f,slow的遍历步长为s,则当两指针第一次相遇时,fast套了slow一圈,则fast的路程为:a+b+(b+c),slow的路程为a+b,有(a+2b+c)/(a+b)=f / s,当t=2,s=1时,该式变为a+2b+c=2(a+b),则a=c。

由此产生了更简单的方法,fast与slow第一次相遇时,将fast重新拉回X点,两指针以1为步长继续遍历,第二次相遇时的节点即为Y点。


C++代码:

/** * 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) {        ListNode *slow = head;ListNode *fast = head;do{if(!slow||!fast)return NULL;slow=slow->next;fast=fast->next;if(!fast)return NULL;elsefast=fast->next;}while(slow!=fast);slow=head;while(slow!=fast){fast=fast->next;slow=slow->next;}return slow;    }};


0 0