zoukankan      html  css  js  c++  java
  • [leetcode] Linked List Cycle

    今天总结一下用Floyd算法来判断链表中是否有环,如果有环,如何找到环的入口。这一系列问题。

    1、Linked List Cycle Ⅰ

    Given a linked list, determine if it has a cycle in it.

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

    分析:第一个题是比较基本的用Floyd算法判断是否有环的问题。大致思想就是定义两个指针,一个每次走一步,一个每次走两步。如果有环,那么肯定会在某个点两者相等。代码如下:
     1 public class Solution {
     2     public boolean hasCycle(ListNode head) {
     3         if ( head == null ) return false;
     4         ListNode tortoise = head;
     5         ListNode hare = head;
     6         while ( hare.next != null && hare.next.next != null ){
     7             hare = hare.next.next;
     8             tortoise = tortoise.next;
     9             if ( hare == tortoise ) return true;
    10         }
    11         return false;
    12     }
    13 }

        运行时间0ms,这里要注意刚开始的判断和while循环结束条件,因为hare跑的比tortoise快,所以对于循环结束的判断只要判断hare就行了。


    2、Linked List Cycle II

    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.

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

    分析:第二个题目变成求环的入口问题,还是用Floyd算法。代码如下:
     1 public class Solution {
     2     public ListNode detectCycle(ListNode head) {
     3         if ( head == null || head.next == null || head.next.next == null ) return null;
     4         
     5         ListNode tortoise = head;
     6         ListNode hare = head;
     7         
     8         while ( hare.next != null && hare.next.next != null ){
     9             hare = hare.next.next;
    10             tortoise = tortoise.next;
    11             if ( hare == tortoise ) break;
    12         }
    13         if ( hare != tortoise ) return null;
    14         
    15         ListNode ptr1 = head;
    16         ListNode ptr2 = hare;
    17         while ( ptr1 != ptr2 ){
    18             ptr1 = ptr1.next;
    19             ptr2 = ptr2.next;
    20         }
    21         return ptr1;
    22     }
    23 }

          运行时间0ms。注意这里要先判断链表个数是否大于三个,因为成环最小要求就是三个。

          Floyd算法思路还是比较清楚的,代码写的过程也比较简单。这里可以再拔高一点,其实Floyd算法就是Two Pointer的应用,两个指针无论在数组还是在链表中用处都非常大。以后会总结相关的题目。

  • 相关阅读:
    417 Pacific Atlantic Water Flow 太平洋大西洋水流
    416 Partition Equal Subset Sum 分割相同子集和
    415 Add Strings 字符串相加
    414 Third Maximum Number 第三大的数
    413 Arithmetic Slices 等差数列划分
    412 Fizz Buzz
    410 Split Array Largest Sum 分割数组的最大值
    409 Longest Palindrome 最长回文串
    day22 collection 模块 (顺便对比queue也学习了一下队列)
    day21 计算器作业
  • 原文地址:https://www.cnblogs.com/boris1221/p/9355848.html
Copyright © 2011-2022 走看看