• 142. Linked List Cycle II


    题目:

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

    Follow up:
    Can you solve it without using extra space?

    Hide Tags
     Linked List Two Pointers
     

    链接: http://leetcode.com/problems/linked-list-cycle-ii/

    题解:

    使用快慢指针,也就是Floyd's cycle-finding algorithm / Tortoise and the Hare algorithm,注意第一个循环结束后要判断是否有环,假如没有环的话return null。  

    从快慢指针travel的距离得到  a + b + m * λ = 2(a + b) + n *λ, 得知   a + b = (m - n)λ ,  a = (m - n)λ - b。

    就是此时可以设置fast= head,然后fast和slow每次均只前进一步,两指针会在环的起点相遇。

    Time Complexity - O(λ + μ), Space Complexity - O(1)。 λ 是环的周长,μ是环起点的index值。

    public class Solution {
        public ListNode detectCycle(ListNode head) {
             if(head == null || head.next == null)
                return null;
             ListNode fast = head;
             ListNode slow = head;
             
             while(fast != null && fast.next != null){
                fast = fast.next.next;
                slow = slow.next;
                if(fast == slow)
                    break;
             }
             
             if(fast == null || fast.next == null)
                return null;            
             fast = head;
    while(fast != slow){ fast = fast.next; slow = slow.next; } return fast; } }

    Update:

    /**
     * Definition for singly-linked list.
     * class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    public class Solution {
        public ListNode detectCycle(ListNode head) {
            if(head == null || head.next == null)
                return null;
            ListNode fast = head, slow = head;
            
            while(fast != null && fast.next != null) {
                fast = fast.next.next;
                slow = slow.next;
                if(slow == fast)
                    break;
            }
            
            if(fast != slow)
                return null;
            
            fast = head;
            
            while(fast != slow) {
                fast = fast.next;
                slow = slow.next;
            }
            
            return fast;
        }
    }

    二刷:

    跟一刷的方法一样,先用快慢指针确定是否有环,假如有环的话我们设置fast = head,然后两个指针每次走一步,这样碰到的地方就是环的起点。

    Java:

    Time Complexity - O(λ + μ), Space Complexity - O(1)。 λ 是环的周长,μ是环起点的index值。

    /**
     * Definition for singly-linked list.
     * class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    public class Solution {
        public ListNode detectCycle(ListNode head) {
            if (head == null || head.next == null) {
                return null;
            }
            ListNode fast = head, slow = head;
            while (fast != null && fast.next != null) {
                fast = fast.next.next;
                slow = slow.next;
                if (slow == fast) {
                    break;
                }
            }
            if (fast != slow) {
                return null;
            }
            fast = head;
            while (fast != slow) {
                fast = fast.next;
                slow = slow.next;
            }
            return fast;
        }
    }

    三刷:

    将fast重新设置为head之后,两个指针每次走一步。  这样当fast走到环的起点时, slow已经在环内走了 (x 圈 + 周长 - b),所以也是到打环的起点。

    Java:

    /**
     * Definition for singly-linked list.
     * class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    public class Solution {
        public ListNode detectCycle(ListNode head) {
            if (head == null || head.next == null) return null;
            ListNode fast = head, slow = head;
            while (fast != null && fast.next != null) {
                fast = fast.next.next;
                slow = slow.next;
                if (fast == slow) break;
            }
            if (fast != slow) return null;
            fast = head;
            while (fast != slow) {
                fast = fast.next;
                slow = slow.next;
            }
            return slow;
        }
    }

    Reference:

    http://en.wikipedia.org/wiki/Cycle_detection

  • 相关阅读:
    先装Net Framework 后 装 IIS的处理办法
    post请求和get请求的区别
    再说重写IHttpHandler,实现前后端分离
    自定义VS的ItemTemplates 实现任意文件结构
    自动生成 Lambda查询和排序,从些查询列表so easy
    sql表分区
    关于Window Server2008 服务器上无法播放音频文件的解决方案
    Visifire Chart相关属性详解
    SQL Server数据库定时自动备份
    在SQL中 给字符串补0方法
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4438820.html
Copyright © 2020-2023  润新知