找到链表中环的起始点

以前想了好几次没想明白,早上拿笔纸一画就看出来了;

设置slow,fast两个指针,slow每次移动一步,fast每次移动两步;若fast结束前与slow重合则说明有环,若未重合即结束则说明没有环;

第一次重合时,假设从head到环起始位置距离为k,slow移动了n步,则slow在环中移动了n-k步,fast在环中移动了2n-k步;距离差n为环长度的倍数;

所以slow再移动k步将到达环的起始位置;这时再从head出发一个finder指针,移动k步恰好也到了环的起始位置,所以当slow==finder的位置即为所求;

代码:

 1     public ListNode detectCycle(ListNode head) {
 2         if(head == null) return null;
 3         ListNode fast = head;
 4         ListNode slow = head;
 5         do{
 6             slow = slow.next;
 7             fast = fast.next;
 8             if(slow==null || fast==null) return null;
 9             fast = fast.next;
10             if(fast==null) return null;
11         }while(fast != slow);
12
13         ListNode finder = head;
14         while(finder != slow){
15             finder = finder.next;
16             slow = slow.next;
17         }
18         return finder;
19     }
时间: 2024-08-08 19:47:27

找到链表中环的起始点的相关文章

Linked List Cycle II--寻找单链表中环的起始点

题目要求 Given a linked list, return the node where the cycle begins. If there is no cycle, returnnull. Follow up: Can you solve it without using extra space? 如何找到环的第一个节点? 根据题目意图,我们可以构建如下模型: 设:链表头是X,环的第一个节点是Y,slow和fast第一次的交点是Z.各段的长度分别是a,b,c,如图所示.环的长度是L.s

56 - 链表中环的入口节点

题目: 一个链表中包含环,如何找出环的入口节点? 例如 1->2->3->4->5->6->(3) ; 的链表中,环的入口及诶到哪是节点 3. 解析: 首先找到链表中的环:定义2个指针,一个快指针一次走2步,一个慢指针一次走1步,如果2个指针能够相遇,证明有环. 统计链表中环的长度:从相遇指针开始,固定 1 个指针,另一个指针从相遇指针走,当2个指针再次相遇时,即走了 1 圈,得到环的长度 len. 2个指针指向链表开头,1个指针先走 len 步,另一个指针从头和前一个

C++实现查找链表中环的入口节点

/* * 寻找链表中环的入口节点.cpp * * Created on: 2018年4月10日 * Author: soyo */ #include<iostream> using namespace std; struct Node{ int num; Node * next; }; Node * creat() { Node *head; Node *p; head=new Node; p=head; p->num=10; p->next=NULL; return head;

剑指offer(二十三,二十四,二十五)最小的k个数,连续子数组的最大和,链表中环的入口节点

23:最小的k个数 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 简单题.... function GetLeastNumbers_Solution(input, k) { if(k>input.length) return []; let ans = []; input = input.sort(); //console.log(input.join("").slice(0,4).split

找到链表的倒数第K位

#include<iostream> using namespace std; class node{ public: node():value(0),next(NULL){} ~node(){} int value; node* next; };///be careful this ; node* createlist(int a[],int n) { node* startnode = new node[n]; node* ret = startnode; for(int i = 0;i&

链表中环的入口结点-剑指Offer

链表中环的入口结点 题目描述 一个链表中包含环,请找出该链表的环的入口结点. 思路 若该链表存在环,设置两个指针pSlow和pFast,pSlow每次走一步,pFast每次走两步,当pFast追上pSlow的时候,pFast比pSlow多走的正好是pSlow走的也就是环所包含的节点的个数. 所以,第二次走,一个从头结点开始,另一个从相遇节点开始,最终会在环的入口节点相遇 代码 /* public class ListNode { int val; ListNode next = null; Li

【单链表】找出单链表中环的“入口”

题目: 找出单链表中环的"入口". 解答步骤: 1.用快慢指针判断是否存在环(慢指针走一步,快指针走两步).若存在环则继续下面的计算,若不存在则返回nullptr: 2.记录快慢指针相遇的节点n0. 3.一个指针从链表头结点出发,另一个指针从n0出发,"同步前进",相遇的节点就是环的"入口". 分析: 由于快慢指针所走的"步数"相同,但快指针每一步是慢指针的两倍,所以快慢指针在n0相遇时,快指针所走距离是慢指针的两倍,即: S

链表中环的判断及相关操作

1.链表中是否有环 如果链表中存在环的话,则遍历链表时无法通过观察指针是否为null来判断链表是否结束. 判断链表中是否存在环,需要引入快慢指针(slow 和 fast),slow每次走一步,fast每次走两步, 如果slow和fast会相遇,则说明链表中存在环,否则不存在. 2.链表中环的入口结点查找 首先判断链表中是否有环,如果无环则返回null退出,否则继续. 首先还是使用快慢指针,当两个指针相遇时跳出循环,然后保持fast指针不变,slow指针赋值为头指针, 然后两个指针每次前进一步,当

链表操作---找到链表的中点

在很多链表的算法中,常常需要找到链表的中点. 这里给出一种使用双指针,一次遍历链表就能找到链表中点的方法. 使用一个快指针,每次走两步,一个慢指针,每次走一步.等快指针走到链表底部的时候,慢指针正好走到中点. /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ ListN