• 【Leetcode】142.Linked List Cycle II


    Question:

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

    Note: Do not modify the linked list.

    Tips:

    给定一个链表,如果链表中有环,返回环开始的结点。如果链表无环 返回null。

    思路:

    之前141题(链接),判断链表中是否有环,返回布尔类型的变量。本题还需要返回环开始的结点。解决过程分为以下几步。

    (1)设置两个速度不同的指针,fast与slow。fast的速度是slow的二倍。

    fast = fast.next.next;
    slow = slow.next;

    当两个指针相遇,证明链表存在结点,否则,fast指针先遇到null证明链表内无环。

    (2)在两个指针相遇处切开,则变成了求两个单链表第一个公共结点的问题160(链接)。

    slow路程:S1=L+a;(L链表无环部分长度,a为slow指针走过的环内的弧长)

    fast路程:S2=L+a+n*k;(n表示环内结点长度,k表示 fast指针走过的环的圈数)

    路程=速度*时间。slow的速度*2=fast的速度。相遇代表时间相等。则S1*2=S2。

    2(L+a)=L+a+n*k; ==> L+a=n*k

              ==> L=n*k-a;

    从上面的分析可以看出,链表中,不在环内的长度L=环的长度n - slow走过的弧长。

    这时,新建一个指针,从head开始向后移动,相遇处的指针继续后移,当两个指针再次相遇,则该节点是环开始的第一个结点。

    代码:

    public ListNode detectCycle(ListNode head) {
            ListNode fast = head;
            ListNode slow = head;
            ListNode meet = null;
            while (fast != null) {
                if (fast.next != null) {
                    fast = fast.next;
                    if (fast.next != null) {
                        fast = fast.next;
                        slow = slow.next;
                        if (fast == slow) {
                            //fast与slow相遇
                            meet = slow;
                            break;
                        }
                    } else
                        return null;
                } else
                    return null;
            }
            ListNode haha = head;
            //循环结束,两个指针均指向环开始的结点。
            while (haha != meet) {
                haha = haha.next;
                meet = meet.next;
            }
    
            return meet;
        }

    测试代码:

    public static void main(String[] args) {
            ListNode head1 = new ListNode(1);
            ListNode head2 = new ListNode(2);
            ListNode head3 = new ListNode(3);
            ListNode head4 = new ListNode(4);
            ListNode head5 = new ListNode(5);
            ListNode head6 = new ListNode(6);
            head1.next = head2;
            head2.next = head3;
            head3.next = head4;
            head4.next = head5;
            head5.next = head6;
            head6.next = head3;
            L142LinkedListCycleII l142 = new L142LinkedListCycleII();
            ListNode head = l142.detectCycle(head1);
            if(head!=null){
                System.out.println(head.val);
            }else{
                System.out.println("Null");
            }
            
        }
  • 相关阅读:
    Linq-分页查询
    思维导图软件xmind和mindmanager哪个更好
    Enterprise Architect使用教程
    敏捷开发之Scrum
    总结---4
    判断单链表是否存在环
    设计模式分类
    实用手册:130+ 提高开发效率的 vim 常用命令
    Reverse Linked List II
    Single Number and Single Number II
  • 原文地址:https://www.cnblogs.com/yumiaomiao/p/8486319.html
Copyright © 2020-2023  润新知