zoukankan      html  css  js  c++  java
  • 环形链表

    问题一

    给定一个链表,判断链表中是否有环。

    解题思路:

    可以设定两个指针p与q,初始都指向链表的起始点(head),p每次跳一步而q每次两步。

    若链表中存在环,则p与q一定相遇。

    代码如下:

        public static boolean hasCycle(ListNode head) {
    
            if (head == null) return false;
            ListNode p = head;
            ListNode q = head;
            while (true) {
                if (q == null || q.next == null) return false;
                p = p.next;
                q = q.next.next;
                if (p == q) return true;
            }
        }

    问题二

    给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

    解题思路:

    设定两个指针p与q,初始都指向链表的起始点(head),p每次跳一步而q每次两步。

    设链表中非环节点由m个,环节点有n个。

    当p指针到达环的第一个节点时,p与q都位于环中,p跳了m步,q跳了2m步,p与q相距m步,q与p相距n-m步。

    (如上图所示,m=3,n=7 。当p跳3步到达环的第一个节点时,p与q相距3步,q与p相距4步。)

    由于q每次必p多走一步,故两个指针需要再跳n-m次才能相遇。此时相遇点与环的起始点相距m步,而head与环的起始点也相距m步。

    故head每次跳一步,p每次跳一步,二者的相聚点即是环的第一个节点。

     代码如下:

        public static ListNode detectCycle(ListNode head) {
    
            if (head == null) return null;
            ListNode p = head;
            ListNode q = head;
            while (true) {
                if (q == null || q.next == null) return null;
                p = p.next;
                q = q.next.next;
                if (p == q) break;
            }
    
            while (head != q) {
                head = head.next;
                q = q.next;
            }
            return head;
        }
  • 相关阅读:
    设置linux查看历史命令显示执行时间
    CentOS7.6操作系统安装实例以及Linux版本、哲学思想介绍
    JavaScript 数据结构1
    原生js 正则表达
    js Event事件
    引用类型: 归并方法
    引用类型: 迭代方法
    引用类型 位置方法 indexOf()和 lastIndexOf()
    引用类型 操作方法
    引用类型 重排序方法
  • 原文地址:https://www.cnblogs.com/deltadeblog/p/9180183.html
Copyright © 2011-2022 走看看