Leetcode 141/142 链表成环算法

LinkedList 成环判断

  • Leetcode 算法题 (141. Linked List Cycle, 142. Linked List Cycle II)
  • Floyd Cycle-Detection Algorithm 方法应用

Background

链表环状图
给出一个链表(LinkedList)的第一个Node,判断该链表是否成环,环的长度和起点(Node).


Floyd Cycle-Detection Algorithms

Floyd’s cycle-finding algorithm is a pointer algorithm that uses only two pointers, which move through the sequence at different speeds.

算法思路:

  • 两个指针一起在链表头部跑,一个快指针一次跑2个Node , 一个慢指针一次跑一个Node.
  • 当快指针跑到一个空的节点,该链表未能成环. (慢指针永远跑在快指针的后面)
  • 当慢指针和快指针跑到同一个节点,该链表成环.
  • 跑到同一个指针后,将慢指针移动回链表头部,两个指针同时跑,每次只跑一个节点. 两个指针再次相遇的节点为链表成环的环起点.
  • 跑到同一个指针后,将快指针停止,慢指针再次移动,每次移动一个Node, 再次相遇时所通过的节点数就是链表环的长度.

算法分析:

  • Time-Complexity Analysis:
    - 如果链表未能成环,则时间为整个链表遍历的时间
    B i g − O    N o t a t i o n = O ( n )    t i m e    c o m p l e x i t y Big-O \; Notation = O(n)\; time\; complexity BigONotation=O(n)timecomplexity
    - 如果链表成环,则需要用 O(n) 来判断成环 (n是考虑链表长度+环状的长度*循环遍历次数), 额外多循环一次 O(n + 环长度) 来寻找环的长度,额外循环一次链表长度来寻找成环的起点.
  • Space-Complexity Analysis: 该算法是 two pointer 算法的扩展设计, 只需要使用两个指针, 因此时间复杂度为 O(1) space complexity.

Leetcode 141. Linked List Cycle

问题描述

给定一个链表的第一个节点,查询该链表是否存在环.

链表环状图

Example 1 (pos 不作为输入值在题目中给出, 输入值只有 value 3 所存在的第一个 ListNode)
Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed).

  class ListNode {
      int val;
      ListNode next;
      ListNode(int x) {
          val = x;
          next = null;
      }
  }

解决方案

public boolean hasCycle(ListNode head) {
        if (head == null) return false;
        
        ListNode slow = head;
        ListNode fast = head;
        
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                return true;
            }
        }
        
        return false;
    }

Leetcode 142. Linked List Cycle II

问题描述

给定一个链表的第一个节点,查询该链表环的起点 ListNode. 如果该链表不成环,则返还 null.

链表环状图

Example 1. (pos 不作为输入值在题目中给出, 输入值只有 value 3 所存在的第一个 ListNode)
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.

  class ListNode {
      int val;
      ListNode next;
      ListNode(int x) {
          val = x;
          next = null;
      }
  }

解决方案

public ListNode detectCycle(ListNode head) {
        if (head == null) return null;
        
        ListNode slow = head;
        ListNode fast = head;
        
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                slow = head;
                while (slow != fast) {
                    slow = slow.next;
                    fast = fast.next;
                }
                return fast;
            }
        }
        
        return null;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值