Loading

142-环形链表系列

1、快慢指针解法

假如该链表是循环链表,那我们可以定义两个指针,一个每次向前移动两个节点,另一个每次向前移动一个节点。这就和田径比赛是一样的,假如这两个运动员跑的是直道,那快的运动员和慢的运动员在起点位于同一位置,但快的运动员必将先到达终点,期间这两个运动员不会相遇。而如果绕圈跑的话(假设没有米数限制),跑的快的运动员在超过跑的慢的运动员一圈的时候,他们将会相遇,此刻就是循环链表

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11 bool hasCycle(ListNode* head) 
12 {
13     //两个运动员位于同意起点head
14     ListNode* faster{ head };  //快的运动员
15     ListNode* slower{ head };  //慢的运动员
16 
17     if (head == NULL)  //输入链表为空,必然不是循环链表
18         return false;
19 
20     while (faster != NULL && faster->next != NULL)
21     {
22         faster = faster->next->next;  //快的运动员每次跑两步
23         slower = slower->next;  //慢的运动员每次跑一步
24         if (faster == slower)  //他们在比赛中相遇了
25             return true;  //可以断定是环形道,直道不可能相遇
26     }
27     return false;  //快的运动员到终点了,那就是直道,绕圈跑不会有终点
28 }
29 };
View Code

2、使用set

set的基础结构是红黑树,插入的元素不能重复。

使用到的函数:set.find   set.insert

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode *detectCycle(ListNode *head) {
12         set<ListNode*> s;
13         while(head!=NULL)
14         {
15             if(s.find(head)==s.end())
16             {
17                 s.insert(head);
18                 head=head->next;
19             }
20             else
21             {
22                 return head;
23             }
24         }
25         return NULL;
26         
27     }
28 };
View Code

 

posted @ 2020-03-06 20:10  是凉城吖  阅读(111)  评论(0)    收藏  举报