剑指offer第2版23题:链表中环的入口结点

小渣渣的算法学习笔记:2018秋招备战


数据结构类算法总结:链表


1.题目描述:

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

2.代码实现:

public class Solution23 {
    private static class ListNode {
        int val;
        ListNode next = null;

        ListNode(int val) {
            this.val = val;
        }
    }

    public static void main(String[] args) {
        Solution23 s = new Solution23();
        ListNode l1 = new ListNode(5);
        ListNode l2 = new ListNode(3);
        ListNode l3 = new ListNode(2);
        ListNode l4 = new ListNode(6);
        ListNode l5 = new ListNode(8);
        ListNode l6 = new ListNode(9);
        l1.next = l2;
        l2.next = l3;
        l3.next = l4;
        l4.next = l5;
        l5.next = l6;
//        l6.next = l3;
        ListNode t = s.entryNodeOfLoop(l1);
        if(t != null){
            System.out.println(String.format("链表中结点%d是环的入口结点",t.val));
        }else{
            System.out.println("链表中不存在环");
        }
    }
    //在链表存在环的前提下找到环中的任意一个结点
    public ListNode meetingNode(ListNode head){
        if(head == null) return null;
        ListNode slow = head.next;
        if(slow == null) return null;
        ListNode fast = slow.next;
        while(fast != null && slow != null){
            if(fast == slow) return fast;
            slow = slow.next;
            fast = fast.next;
            if(fast != null){
                fast = fast.next;
            }
        }
        return null;
    }

    //求出环中的结点数目,找到环的入口结点
    public ListNode entryNodeOfLoop(ListNode head){
        ListNode meetingNode = meetingNode(head);
        if(meetingNode == null) return null;
        //得到环中的节点数目
        int nodesInLoop = 1;
        ListNode pnode1 = meetingNode;
        while(pnode1.next != meetingNode){
            pnode1 = pnode1.next;
            ++nodesInLoop;
        }
        //先移动pnode1,次数为环中结点个数
        pnode1 = head;
        for(int i=0;i < nodesInLoop;++i){
            pnode1 = pnode1.next;
        }
        //再移动pnode1和pnode2
        ListNode pnode2 = head;
        while(pnode1 != pnode2){
            pnode1 = pnode1.next;
            pnode2 = pnode2.next;
        }
        return pnode1;//返回环的入口结点
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42561115/article/details/80945488
今日推荐