zoukankan      html  css  js  c++  java
  • 链表中环的入口结点

    题目描述

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

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

    题目链接

    粗暴方法,供出利器map:
    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
            val(x), next(NULL) {
        }
    };
    */
    class Solution {
    public:
        ListNode* EntryNodeOfLoop(ListNode* pHead)
        {
    		if(pHead == NULL)
                return NULL;
            map<ListNode*, int> cnt;
            while(pHead != NULL)
            {
                cnt[pHead]++;
                if(cnt[pHead] == 2)
                    return pHead; 
                
                pHead = pHead->next; 
            }
            
            return NULL; 
        }
    };
    
    


    烧脑解法:
    • 第一步: 找环中相汇点。分别用p1,p2指向链表头部,p1每次走一步,p2每次走二步,直到p1==p2找到在环中的相汇点。
    • 第二步: 找环的入口。接上步,当p1p2时,p2所经过节点数为2x, p1所经过节点数为x,设环中有r个节点, p2比p1多走 n (n >= 1)圈. 有2x=nr+x; 可以看出p1实际走了n个环的步数,再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1p2; 此时p1和 p2指向环的入口.
    简单证明:

    设起点到相遇点距离为x,起点到入口点距离为y,环长度为r, 则快慢指针相遇时,满足2x-x=nr,n为快指针在环中转的圈数。于是 x=nr 快慢指针相遇点距环入口点距离 x-y(正负没关系) 。相遇后,快指针从起点重新开始以步长为1速度开始走,经过距离y到达环入口点,慢指针走y步后距离环入口点距离为 x-y+y = x = nr,即走到了环入口点,两个指针相遇!

    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
            val(x), next(NULL) {
        }
    };
    */
    class Solution {
    public:
        ListNode* EntryNodeOfLoop(ListNode* pHead)
        {
    		if(pHead == NULL)
                return NULL; 
            ListNode* fastPos = pHead; 
            ListNode* slowPos = pHead;
            while(fastPos != NULL && slowPos != NULL)
            {
                if(fastPos->next != NULL)
                {
                    fastPos = fastPos->next; 
                    fastPos = fastPos->next; 
                }
                else
                    return NULL; 
                
                slowPos = slowPos->next; 
                
                if(slowPos == fastPos)
                    break;
            }
            
            if(fastPos == NULL || slowPos == NULL)
                return NULL;
            
            fastPos = pHead; 
            while(fastPos != slowPos)
            {
                fastPos = fastPos->next; 
                slowPos = slowPos->next; 
            }
            
            return fastPos; 
        }
    };
    


  • 相关阅读:
    tar.xz文件如何解压
    warnings and errors when executing : make -j4
    ubuntu关机
    Linux系统kernel编译替换升级
    安装linux内核
    二叉树的度数和节点数的关系
    刷题--将搜索二叉树转换成双向链表
    刷题--二叉搜索树与双向链表
    刷题--删除链表中重复的节点
    四舍五入输出
  • 原文地址:https://www.cnblogs.com/acm1314/p/7056463.html
Copyright © 2011-2022 走看看