打败算法 —— 相交链表

本文参考

出自LeetCode上的题库 —— 相交链表,根据官方的双指针解法,本文从另一个角度进行分析

https://leetcode-cn.com/problems/intersection-of-two-linked-lists/

相交链表问题

给定两个单链表的头节点 headA 和 headB ,找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null

示例1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'

示例 2:
输入:intersectVal= 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at '2'

示例 3:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null

解题思路

到目前为止已经做了很多双指针的解法,就不考虑遍历一遍链表,把结点存到链表里再进行判断的普通做法了。官方提供的双指针解法很巧妙,假设链表A比链表B长,那么两条链表的指针同时开始移动时,链表B的指针会率先到达链表的末尾。此时,链表B的指针下一步从链表A的起始位置移动,同理链表A的指针到达链表末尾后,下一步从链表B的起始位置移动。这种做法的本质,类似于填补上了两条链表长度上的差值。

因此,可以有另一种思考方式,仍然假设链表A比链表B长,链表B的指针到达末尾后,计算链表A的指针还需要走多少步才会到达末尾,得到计数值cnt。然后两个链表再从头开始遍历,只不过链表A的指针要提前走好cnt个步数,相当于两个链表的指针从距离相交结点相同距离的起点出发,若相交结点存在,则一定能够相遇。

双指针解法

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

class
Solution:
  def get_intersection_node(self, headA: ListNode, headB: ListNode) -> ListNode:
    if not (headA and headB):
      return None

    curr_a = headA
    curr_b = headB

    # 让较长的一个链表首先到达末尾 

    while curr_a and curr_b:
      if curr_a == curr_b:
        return curr_a
      curr_a = curr_a.next
      curr_b = curr_b.next

    cnt = 0
    if curr_a:
      # 链表较长,计算 a 比 b 长多少 

      while curr_a:
        curr_a = curr_a.next
        cnt += 1
      # 重新从头开始,让 a 事先走比 b 多出来的步数 

      curr_a = headA
      curr_b = headB
      while cnt:
        curr_a = curr_a.next
        cnt -= 1
    elif curr_b:
      # 链表较长,计算 b 比 a 长多少 

      while curr_b:
        curr_b = curr_b.next
        cnt += 1
      # 重新从头开始,让 b 事先走比 a 多出来的步数 

      curr_a = headA
      curr_b = headB
      while cnt:
        curr_b = curr_b.next
        cnt -= 1
    else:
      # 两个链表一样长,但是没有相交的结点 

      return None

    # 补充多余步数后,一起开始移动 

    while curr_a != curr_b:
      curr_a = curr_a.next
      curr_b = curr_b.next

    if curr_a:
      return curr_a
    else:
      return None

posted @ 2022-03-06 10:12  咕~咕咕  阅读(40)  评论(0编辑  收藏  举报