【算法题】链表中环的入口结点

链表中环的入口结点

http://nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4?tpId=196&tqId=37047&rp=1&sourceUrl=%2Fexam%2Foj%3FquestionJobId%3D10%26subTabName%3Donline_coding_page&difficulty=undefined&judgeStatus=undefined&tags=&title=

这题要找出链表中环的入口,如果链表中没有环,则返回空。前面我们讲过《判断链表是否有环》,所以我们可以根据前面的解来判断链表是否有环,如果没环,自然就不可能有环的入口。如果有环我们再来找出环的入口,怎么找呢?如下图所示。 alt

在相遇点快指针走过的距离是: a+c+(b+c)*m,其中 b+c 是环的周长, m 是快指针在环上转了 m 圈之后和慢指针相遇。慢指针走过的距离是: a+c+(b+c)*n,其中 n 是慢指针在环上转了 n 圈之后和快指针相遇,很明显 n < m

由于快指针每次走两步,慢指针每次走一步,所以快指针走的距离是慢指针的 2 倍,也就是:

a+c+(b+c)*m = 2*(a+c+(b+c)*n)

整理之后可以得到:a+c= (b+c)*(m-2*n),也就是说 a+c 的长度等于 (m-2*n) 个环的长度。在整理一下又可以变成:

a = (b+c)*(m-2*n-1)+b。其中 (b+c)*(m-2*n-1) 是在环上走了整整 (m-2*n-1) 圈。

这个时候如果我们使用两个指针,一个从起始位置开始,一个从相遇点开始,每次都走一步,最终它们一定会在环的入口相遇。


    public ListNode EntryNodeOfLoop(ListNode pHead) {
        ListNode slow = pHead;// 快指针
        ListNode fast = pHead;// 慢指针
        while (fast != null && fast.next != null) {
            // 快慢指针,快指针每次走两步,慢指针每次走一步
            fast = fast.next.next;
            slow = slow.next;
            if (slow == fast) {// 如果相遇,说明有环
                // 确定有环之后才能找环的入口
                while (pHead != slow) {
                    // 两指针,一个从头结点开始,一个从相遇点
                    // 开始每次走一步,直到再次相遇为止
                    pHead = pHead.next;
                    slow = slow.next;
                }
                return slow;
            }
        }
        return null;
    }

public:
    ListNode *EntryNodeOfLoop(ListNode *pHead) {
        ListNode *slow = pHead;// 快指针
        ListNode *fast = pHead;// 慢指针
        while (fast && fast->next) {
            // 快慢指针,快指针每次走两步,慢指针每次走一步
            fast = fast->next->next;
            slow = slow->next;
            if (slow == fast) {// 先判断是否有环,
                // 确定有环之后才能找环的入口
                while (pHead != slow) {
                    // 两指针,一个从头结点开始,一个从相遇点
                    // 开始每次走一步,直到再次相遇为止
                    pHead = pHead->next;
                    slow = slow->next;
                }
                return slow;
            }
        }
        return nullptr;
    }

各大厂算法面试题已经整理好了,请看这里:《算法专栏》

#笔试#

为了应对春招和秋招找工作,我经过长时间的收集和整理了各大厂的算法面试题,所有的算法题我都已经做了实现,大家可以根据自己需要面试的大厂选择练习即可。适宜人群: 在校生、社招求职者及自学者。

全部评论

相关推荐

网安已死趁早转行:山东这地方有点说法
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务