题目描述:
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
来源:Leetcode 141
地址:https://leetcode.cn/problems/linked-list-cycle/
思路:
反转链表。
1.如果头结点是空的,或者头结点指向的下一个结点是空的,则不可能形成环,直接返回false。
2.新建一个结点pre和p,pre=head,p=head->next,此时,pre指向p,pre和p是两个相邻的结点,然后让pre指向空白。
3.开始循环,如果p->next不为空指针,那么用temp来储存p->next,然后让p->next = pre,此时,p指向了pre,p和pre之间的指向关系反转。下一步,让pre和p同时向前进一步,开始下一次循环,使得前进后的pre和p的指向关系也反转,如此循环往复,直到所有节点的指向关系都反转,就完成了链表的反转了。
4.最后一步,如果链表不存在环,那么pre和p就会一路前进下去,没有回头的机会,最后p前进到链表最后一个结点,无法再前进,循环结束,而此时p位于链表最后一个结点,与链表原头节点head不相等,则返回false,说明该链表没有环。
5.如果链表存在环,那么在pre和p在前进到一定程度时,会通过环,回到链表前面,而此时链表的指向已经反转,因此pre和p会沿着反方向前进,最后p回到最开始的节点,循环结束。此时p与链表原节点head相等,返回true。
//Language: C++
//Defination 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 == nullptr || head->next == nullptr) return false;
ListNode* pre = head, p = head->next;
pre->next = nullptr;
while(p->next != nullptr){
ListNode* temp = p->next;
p->next = pre;
pre = p;
p = temp;
}
if(p == head) return true;
return false;
}
};