开宗明义:本系列基于小象学院林沐老师课程《面试算法 LeetCode 刷题班》,刷题小白,旨在理解和交流,重在记录,望各位大牛指点!
Leetcode学习之链表(3)
1、链表求环 Leetcode 141.142
题目来源:
L
e
e
t
c
o
d
e
141.142
L
i
n
k
e
d
L
i
s
t
C
y
c
l
e
Leetcode \ 141.142 \ Linked \ List \ Cycle
Leetcode 141.142 Linked List Cycle
题目描述:已知链表中可能存在环,有有环返回环起始节点,否则返回
N
U
L
L
NULL
NULL。
要求描述:
1.1 思路①(set使用)
思路①:
- 遍历链表,将链表中节点所对应的指针(地址),插入 s e t set set 。
- 在遍历时插入节点前,在
s
e
t
set
set 中查找,第一个在
s
e
t
set
set 中发现的节点地址,即为链表环的起点。
测试代码:
#include <stdio.h>
#include <set>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) :val(x), next(NULL) {}
};
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
set<ListNode *> node_set;//设置node_set
//插入节点前,在set中查找,第一个在set中发现的节点地址,即为链表环的起点
while (head) //遍历链表
{
if (node_set.find(head) != node_set.end()) //如果在node_set已经出现
return head;
node_set.insert(head);//将节点插入node_set
head = head->next;
}
return NULL; //没有环,返回空
}
};
int main()
{
ListNode a(1),b(2),c(3),d(4),e(5),f(6),g(7);
a.next = &b;
b.next = &c;
c.next = &d;
d.next = &e;
e.next = &f;
f.next = &g;
g.next = &c;
Solution solve;
ListNode *node = solve.detectCycle(&a);
if (node) {
printf("%d\n", node->val);
}
else
{
printf("NULL\n");
}
system("pause");
return 0;
}
效果图:
1.2 思路②(快慢指针)
思路②:从
h
e
a
d
head
head出发,一快一慢两指针,快指针是慢指针速度的两倍。所以两指针相遇的节点设为
m
e
e
t
meet
meet,然后
h
e
a
d
head
head与
m
e
e
t
meet
meet指针在各自位置上同时出发,相遇就是环的起点。
测试代码:
#include <stdio.h>
#include <set>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) :val(x), next(NULL) {}
};
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *fast = head;//快指针
ListNode *slow = head;//慢指针
ListNode *meet = NULL;//相遇的节点
while (fast){//链表无环且节点个数为偶数个
slow = slow->next;
fast = fast->next;
if (!fast) { //fast遇到链表尾,则无环,且节点为奇数个,因为遇到null,不会执行下一个fast一步
return NULL;
}
fast = fast->next;//fast再走一步
if (fast == slow) {
meet = fast;//fast与slow相遇,记录相遇位置
break;
}
}
if (meet == NULL)
{
return NULL; //
}
while (head && meet){ //head与meet指针同时出发,相遇就是环的起点
if (head == meet) {
return meet;
}
head = head->next;
meet = meet->next;
}
return NULL;
}
};
int main()
{
ListNode a(1),b(2),c(3),d(4),e(5),f(6),g(7);
a.next = &b;
b.next = &c;
c.next = &d;
d.next = &e;
e.next = &f;
f.next = &g;
g.next = &c;
Solution solve;
ListNode *node = solve.detectCycle(&a);
if (node) {
printf("%d\n", node->val);
}
else
{
printf("NULL\n");
}
system("pause");
return 0;
}
效果图: