• 链表中环的起点


    题目描述

    一个链表中包含环,请找出该链表的环的入口结点。
    /*
    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 alt="" 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;
        }
    };
    

      

    拥抱明天! 不给自己做枷锁去限制自己。 别让时代的悲哀,成为你人生的悲哀。
  • 相关阅读:
    js数组
    关于编程,程序员的一些语录
    css心得
    js函数
    一些电脑基础知识
    gnome3安装
    C学习小记
    ubuntu重装系统后
    elinks文字浏览器
    快捷方式
  • 原文地址:https://www.cnblogs.com/dd2hm/p/7396778.html
Copyright © 2020-2023  润新知