剑指offer之面试题23:链表中环的入口节点

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

题目:如果一个链表中包含环,如何找出环的入口节点?例如在下图中,环的入口节点是节点3。

在这里插入图片描述
解题思路:

  • 第一步,如何确定链表中包含环?

    定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步。如果走的快的指针追上了走的慢的指针,那么链表中就包含环;如果走得快的指针走到了链表的末尾都没有追上第一个指针,那么链表就不包含环。

  • 第二步,如何找到环的入口。先定义两个指针 p1 和 p2 。如果链表中的环有 n 个节点,则指针 p1 先在链表上向前移动 n 步,然后两个指针以相同的速度向前移动。当第二个指向环的入口节点时,第一个指针已经围绕着环走了一圈,又回到了入口节点。

  • 第三步,如何得到环中节点的数目。在第一步中,我们用一快一慢两个指针,如果两个指针相遇,则表明链表中存在环。两个指针相遇的节点一定在环中。可以从这个节点触发,一边继续向前移动一边计数,当再次回到这个节点时,就可以得到环中的节点数了。

代码实现:

package Question23;

public class T01 {
    public static void main(String[] args) {
        Node node1 = new Node(1);
        Node node2 = new Node(2);
        Node node3 = new Node(3);
        Node node4 = new Node(4);
        Node node5 = new Node(5);
        Node node6 = new Node(6);

        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        node6.next = null;

        System.out.println(solve(null));
    }

    public static Node solve(Node node) {
        Node meeting = meetingNode(node);
        if(meeting == null) return null;
        int count = 1;
        Node temp = meeting.next;
        while(meeting != temp) {
            count++;
            temp = temp.next;
        }
        Node pNode1 = node;
        Node pNode2 = node;
        while(pNode2 != null && count > 0) {
            pNode2 = pNode2.next;
            count--;
        }
        while(pNode1 != pNode2) {
            pNode1 = pNode1.next;
            pNode2 = pNode2.next;
        }
        return pNode1;
    }

    public static Node meetingNode(Node node) {
        if(node == null) return null;
        Node pLow = node;
        Node pFast = node.next;
        while(pLow != null && pFast != null) {
            pLow = pLow.next;
            pFast = pFast.next;
            if(pFast != null) pFast = pFast.next;
            else return null;
            //如果两个指针相遇,说明有环,并返回这个相遇的节点
            if(pLow == pFast) return pLow;
        }
        return null;
    }
}

class Node {
    int id;
    Node next;

    public Node(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Node{" +
                "id=" + id +
                '}';
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值