• 链表中环的入口节点


      

    题目描述

    对于一个给定的链表,返回环的入口节点,如果没有环,返回null
    拓展:
    你能给出不利用额外空间的解法么?
     
     
     

     牛客上的一个题目,判断是否有环,使用快慢指针即可,要找到环的入口就需要再分析一下

    方法一:

    因为快指针的速度是慢指针的2倍,所以当快慢指针第一次相遇时,快指针走过的路程(暂时就这么叫)是慢指针的2倍

    所以可以得出如下等式:假设快慢指针相遇时,快指针已经绕了n圈

    2(x+y)=x+y+n*(y+z)

    整理一下可得

    x=(n-1)(y+z)+z

    可以发现y+z恰好是环的一圈,x等于n-1圈环加z,所以第一次相遇后慢指针回到起点,快慢指针以相同的速度向前走(一次走一格),

    当慢指针走了x长的路程时,快指针绕了n-1圈并且还走了z,这时他们恰好相遇在入口(真巧)

     1 /**
     2  * Definition for singly-linked list.
     3  * class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) {
     7  *         val = x;
     8  *         next = null;
     9  *     }
    10  * }
    11  */
    12 public class Solution {
    13     public ListNode detectCycle(ListNode head) {
    14         if(head == null){
    15             return null;
    16         }
    17         ListNode slow = head;
    18         ListNode fast = head;
    19         while(fast != null && fast.next != null){
    20             fast = fast.next.next;
    21             slow = slow.next;
    22             if(fast == slow){
    23                 break;
    24             }
    25         }
    26         if(fast == null || fast.next == null){
    27             return null;
    28         }
    29         slow = head;
    30         while(slow != fast){
    31             slow = slow.next;
    32             fast = fast.next;
    33         }
    34         return slow;
    35     }
    36 }

    方法二(可先看代码):

     1 /**
     2  * Definition for singly-linked list.
     3  * class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) {
     7  *         val = x;
     8  *         next = null;
     9  *     }
    10  * }
    11  */
    12 public class Solution {
    13     public ListNode detectCycle(ListNode head) {
    14         if(head == null || head.next == null){
    15             return null;
    16         }
    17         ListNode slow = head,fast = head.next;
    18         ListNode t = head.next;
    19         while(slow != fast){
    20             if(fast == null || fast.next == null){
    21                 return null;
    22             }
    23             slow = slow.next;
    24             fast = fast.next.next;
    25             if(slow == fast)//这里必须加判断,否则会出现空指针异常
    26             t = fast.next;
    27         }
    28         
    29         slow = head;
    30         while(slow != t ){
    31             slow = slow.next;
    32             t = t.next;
    33         }
    34         return slow;
    35     }
    36 }

    方法二是看了leetcode141的题解才有的想法,但是没有方法一,直接方法二就有点困难。我觉得方法二有点鸡肋

  • 相关阅读:
    微信Jssdk 认证签名
    枚举的变换
    mysql 事务
    Java中的堆和栈
    mysql-索引
    mysql-事务隔离 为什么你改了我还看不见
    mysql 一次更新语句是如何执行的
    mysql-一条sql的执行过程
    随笔
    设计模式之装饰者
  • 原文地址:https://www.cnblogs.com/yu-xia-zheng-ye/p/13621875.html
Copyright © 2020-2023  润新知