链表中环的起点

题目描述

一个链表中包含环,请找出该链表的环的入口结点。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
	ListNode* fast=pHead;
        ListNode* slow=pHead;

        while(fast->next !=NULL ) {
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow) {
                break;
            }
        }

        if(fast->next==NULL) {
            return NULL;
        }

        fast=pHead;
        while(fast!=slow) {
            fast=fast->next;
            slow=slow->next;
        }
    	return slow;
    }
};

  您的代码已保存
运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。
case通过率为0.00%

通过重新查阅程序,发现部分错误: while(fast=slow)应该写成:while(fast!=slow)。 while(fast->next !=NULL )部分改成while(fast!=NULL &&fast->next !=NULL ) 即可。

最终运行成功。

http://blog.csdn.net/lalor/article/details/7628332

思路:leetcode上也有这道题,具体思想是,两个指针fast和slow,fast以slow两倍速度前进,
如果没有环,那么fast和slow不会相遇此时返回null;如果有环,那fast和slow肯定会再次相遇
相遇的时候,fast刚好比slow多走了一圈环的长度。 <img  src="https://uploadfiles.nowcoder.com/images/20170422/943729_1492841744777_3BB680C9CBA20442ED66C5066E1F7175"> 用图来描述下,当fast与slow相遇时,fast走过的距离为a + b + c + b,而slow走过的距离为
a + b,因为fast是slow速度的两倍,则有a+b+c+b = 2*(a+b),登出a=c;此时slow节点所处X处
到环起点Y处的距离a和X节点到Y处距离c其实是相等的,此时第三个指针p从x处,以和slow指针
相同的速度前进,当它两相遇时,即为环的起点Y处!
 
public class Solution {
 
    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        ListNode fast = pHead;
        ListNode slow = pHead;
        while(fast !=null && fast.next !=null) {
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) {
                ListNode p = pHead;
                while( p != slow) {
                    p = p.next;
                    slow = slow.next;
                }
                return p;
            }
        }
        return null;
    }
}

  

/*
时间复杂度为O(n),两个指针,一个在前面,另一个紧邻着这个指针,在后面。
两个指针同时向前移动,每移动一次,前面的指针的next指向NULL。
也就是说:访问过的节点都断开,最后到达的那个节点一定是尾节点的下一个,
也就是循环的第一个。
这时候已经是第二次访问循环的第一节点了,第一次访问的时候我们已经让它指向了NULL,
所以到这结束。
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if (!pHead->next)
            return NULL;
        ListNode* previous = pHead;
        ListNode* front = pHead ->next;
        while (front)
        {
            previous->next = NULL;
            previous = front;
            front = front->next;
        }
        return previous;
    }
};

  

时间: 2024-10-12 01:25:43

链表中环的起点的相关文章

剑指Offer对答如流系列 - 链表中环的入口节点

面试题23:链表中环的入口节点 问题描述 一个链表中包含环,如何找出环的入口结点?例如,在图中的链表中,环的入口结点是结点3. 链表的结构 public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } 问题分析 首先不能忽略链表中不包含环的情况,第一件事情必须先确定链表是否有环:我们可以使用两个引用,一个跑的快.一个跑的慢,同时出发,跑的快的追上跑的慢的自然说明有环.(

56 - 链表中环的入口节点

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

链表中环的入口结点-剑指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指针赋值为头指针, 然后两个指针每次前进一步,当

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

剑指offer 55. 链表中环的入口结点

55. 链表中环的入口结点 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null 法一:(我没看懂) 思路:https://blog.nowcoder.net/n/76e8af2d2fad49f990cde6e6b60a4d79?f=comment 快慢指针,快指针一次走两步,慢指针一次走一步,相遇后,快指针回到头结点,以一次一步的速度和慢指针一起走,再次相遇的结点即是环的入口点 1 public class Solution { 2 3 public ListNo

剑指offer:链表中环的入口节点

题目描述给一个链表,若其中包含环,请找出该链表的环的入口节点,否则,输出null. # -*- coding: utf-8 -*- # @Time : 2019-04-23 22:40 # @Author : Jayce Wong # @ProjectName : job # @FileName : entryNodeOfLoop.py # @Blog : https://blog.51cto.com/jayce1111 # @Github : https://github.com/SysuJa