面试题 23:链表中环的入口节点

最后都变了- 提交于 2020-03-18 23:58:28

3 月,跳不动了?>>>

题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

思路

  • 书中解法
  1. 查询是否有环,设定两个指针,第一个慢指针每次走一步,第二个快指针每次走两步。当快指针超过慢指针时,即链表中有环。
  2. 查询环中的节点数,可从 1 中获得在环中的某个节点,通过这个节点循环遍历,可以回到此节点,由此计算节点数 nodesInLoop。
  3. 从链表头开始,设定两个指针,第一个指针先走环中节点数 nodesInLoop 次数,然后第二个指针与第一个指针开始同时遍历,每次走一步,到两指针相会时,所指向的节点即为入口节点。
  • 其他解法

双指针法

https://leetcode-cn.com/problems/linked-list-cycle-ii/

代码

  • 书中解法
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode meetingNode = meetingNode(head);
        // 链表中无环,直接返回 null
        if (meetingNode == null) {
            return null;
        }

        // 得到环中节点的数目
        int nodesInLoop = 1;
        ListNode pNode1 = meetingNode;
        while (pNode1.next != meetingNode) {
            pNode1 = pNode1.next;
            nodesInLoop++;
        }

        // 先移动 pNode1,次数为环中节点的数目
        pNode1 = head;
        while (pNode1 != null && nodesInLoop > 0) {
            pNode1 = pNode1.next;
            nodesInLoop--;
        }

        // 再移动 pNode1 与 pNode2
        ListNode pNode2 = head;
        while (pNode1 != pNode2) {
            pNode1 = pNode1.next;
            pNode2 = pNode2.next;
        }

        return pNode2;
    }

    /**
     * 查询链表中是否包含环
     *
     * @param pHead
     * @return
     */
    private ListNode meetingNode(ListNode pHead) {
        // 空链表,直接返回 null
        if (pHead == null) {
            return null;
        }

        ListNode pSlow = pHead;
        // 只有一个节点,直接返回 null
        if (pSlow.next == null) {
            return null;
        }

        ListNode pFast = pSlow.next;
        // 遍历,直到慢指针与快指针相会并返回
        while (pSlow != null && pFast != null) {
            if (pFast == pSlow) {
                return pFast;
            }

            pSlow = pSlow.next;

            pFast = pFast.next;
            if (pFast != null) {
                pFast = pFast.next;
            }
        }

        // 执行到这里,说明链表中无环
        return null;
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!