【算法训练】剑指offer#52 两个链表的第一个公共节点

一、描述

两个链表的第一个公共节点

输入两个链表,找出它们的第一个公共节点。

如下面的两个链表:

2X7WWT.png

在节点 c1 开始相交。

示例 1:

2X7hSU.png

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:

2X74lF.png

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Reference of the node with value = 2
输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:

2X7RYV.png

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
解释:这两个链表不相交,因此返回 null。

二、思路

  • 取出两个链表中的所有value并存入两个list中,之后注意比较list中的值,存在相等就输出,没有就返回None
class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        # 如果存在空链表,就直接返回None
        if not headA or not headB: return None
        # 用于遍历链表
        valueListA, valueListB = headA, headB
        # 用于存储两个链表中的value
        listA, listB = [], []
        # 遍历并将value存入两个list中
        while valueListA:
            listA.append(valueListA.val)
            valueListA = valueListA.next
        while valueListB:
            listB.append(valueListB.val)
            valueListB = valueListB.next
        # 找相等的value
        for i in listA:
            if i in listB:
                return i
        return None

  • 然后发现理解错题意了(明明是题说的不明白吧...),题的意思应该是返回第一个公共节点,而不是返回值,所以最简单的话,就循环遍历好了
  • 仔细想了想还是不对,如果这样的话是没有办法确保相等节点是第一个公共节点的,比如[4,1,8,4,5], [5,0,1,8,4,5]返回的将是4
  • 我觉得可以将两个链表进行逆序,然后对产生的两个新链表进行遍历,当出现不相等节点时,前一个结点就是第一个公共节点(可这样时间复杂度就大了吧....)
  • 终于想到了....如果两个链表存在公共节点,那么两个链表应该是从尾端对齐的,也就是说,公共节点应该从两个链表长度差的节点开始一一比较,用符号表示的话,链表A,B的长度分别为lengthA,lengthB,则应该从较长链表的第|lengthA-lengthB|位开始比较(唉,这样还需要知道两个链表的长度)

三、解题

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

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        # 如果存在空链表,就直接返回None
        if not headA or not headB: return None
        # 用于遍历链表
        listA, listB = headA, headB
        # 两个链表长度
        lengthA, lengthB = 1, 1
        # 获取两个链表的长度
        while listA:
            listA = listA.next
            lengthA += 1
        while listB:
            listB = listB.next
            lengthB += 1

        # 用于遍历链表
        listA, listB = headA, headB
        if lengthA > lengthB:
            # 开始比较的位置
            judgeLoc = lengthA - lengthB
            while judgeLoc != 0 :
                listA = listA.next
                judgeLoc -= 1
        else:
            # 开始比较的位置
            judgeLoc = lengthB - lengthA
            while judgeLoc != 0 :
                listB = listB.next
                judgeLoc -= 1
        # 此时两个链表处于对齐的状态
        while listA:
            # 如果节点相等,则返回该公共节点
            if listA == listB:
                return listA
            listA = listA.next
            listB = listB.next
        # 如果没有公共节点,则返回None
        return None
posted @ 2022-01-18 19:30  小拳头呀  阅读(26)  评论(0编辑  收藏  举报