打败算法 —— 环形链表 II

本文参考

出自LeetCode上的题库 —— 环形链表II,哈希表和快慢指针两种解法都需要O(n)的时间,但快慢指针仅占用O(1)的空间

https://leetcode-cn.com/problems/linked-list-cycle-ii/

环形链表问题

给定一个链表的头节点 head,返回链表开始入环的第一个节点(不允许修改链表)
如果链表无环,则返回null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环

示例1:
输入:head = [3,2,0,-4]
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点

示例2:
输入:head = [1,2]
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点

示例3:
输入:head = [1]
输出:返回 null
解释:链表中没有环

解题思路

首先是特殊情况,当没有节点,或有节点却不存在环的情况下,容易通过节点或节点的next指针是否空进行判断

当节点间存在环路时,第一种直观的解法,使用一个指针沿着链路走下去,每走一步将节点存入set集合,当碰到重复出现的节点时,该节点就是环路的入口;

第二种解法需要应用两遍双指针,可能刚接触这道题时已经想到了快慢指针,但是我们无法保证快指针和慢指针相遇的位置一定是环路的入口,以至于否定了这种解法。此处需要一定的数学分析,在快慢指针相遇的位置引入第三个指针:

令总节点数为n,头节点为head,环路的入口节点为entry,环路中快慢指针相遇的节点位置为meet,定义距离a=Distance(head,entry),距离b=Distance(entry,meet),距离c=Distance(meet,entry),满足n=a+b+c

当快慢指针相遇时,快指针走过的路径长度为dfast=a+n(b+c)+b,慢指针走过的路径长度为dslow=a+b,我们预先设置快指针每次走两步,慢指针每次走一步,则dfast=2dslow=a+n(b+c)=2(a+b),化简得a=c+(n1)(b+c)a的长度是c的长度加上(n1)圈的环路长度

因此,我们引入第三个指针ptr,慢指针从相遇位置开始移动,ptr从头指针开始移动,由公式a=c+(n1)(b+c)可知,二者相遇的位置即为环路的路口

哈希表解法

class ListNode:
  def __init__(self, x):
    self.val = x
    self.next = None

class
Solution:

  def detect_cycle_1(self, head: ListNode) -> ListNode:
    if head is None or head.next is None:
      return None

    node_set = set()
    curr_node = head
    while curr_node not in node_set:
      node_set.add(curr_node)
      if curr_node.next is None:
        return None
      else
:
        curr_node = curr_node.next
    return curr_node

快慢指针解法

def detect_cycle_2(self, head: ListNode) -> ListNode:
  slow = fast = head
  while fast is not None:
    # 慢指针每次走一步 

    slow = slow.next
    if fast.next is None:
      return None
    # 快指针每次走两步 

    fast = fast.next.next
    # 快慢指针相遇 

  if fast == slow:
    ptr = head
    # 建立新的双指针走法 

    while ptr != slow:
      ptr = ptr.next
      slow = slow.next
      return ptr
    return None

posted @   咕~咕咕  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示