📜  两个链表的并集和相交|设置2(使用合并排序)(1)

📅  最后修改于: 2023-12-03 15:35:56.949000             🧑  作者: Mango

两个链表的并集和相交|设置2(使用合并排序)

在面试过程中,经常会遇到链表相关的问题,其中比较经典的问题就是两个链表的并集和相交问题。本文将介绍如何用合并排序的方式解决这个问题。

问题描述

给定两个可能有交点的单向链表,写一个函数判断它们是否相交(即存在一个节点,它同时在两个链表中出现)。如果相交,返回这个相交点,否则返回null。

例如,链表A: 1→2→3→4→5,链表B: 6→7→8→4→5,则这两个链表相交的节点是4。

解决方案

算法思路

为了解决这个问题,我们可以先对两个链表进行合并排序(Merge Sort),然后再寻找相交点。

合并排序(Merge Sort)的基本思路是将一个大的序列分成两个小的序列,分别对它们进行排序,然后再将两个有序序列合并成一个有序序列。

具体实现中,我们可以使用递归的方式对两个序列分别进行排序,然后再按照顺序将它们合并起来。这个过程涉及到链表的操作,需要注意细节。

代码实现

下面是使用合并排序实现求两个链表的相交点的python代码,其中ListNode是自定义的链表节点类。代码中getIntersectionNode函数是我们需要实现的函数。

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

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        lengthA = self.getListLength(headA)
        lengthB = self.getListLength(headB)

        if lengthA > lengthB:
            for i in range(lengthA - lengthB):
                headA = headA.next
        else:
            for i in range(lengthB - lengthA):
                headB = headB.next

        while headA != None and headB != None:
            if headA == headB:
                return headA

            headA = headA.next
            headB = headB.next

        return None

    def getListLength(self, head: ListNode) -> int:
        length = 0
        while head != None:
            length += 1
            head = head.next

        return length

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

        middle = self.getMiddle(head)
        nextToMiddle = middle.next

        middle.next = None

        left = self.mergeSort(head)
        right = self.mergeSort(nextToMiddle)

        sortedHead = self.sortedMerge(left, right)
        return sortedHead

    def sortedMerge(self, left: ListNode, right: ListNode) -> ListNode:
        if left == None:
            return right
        if right == None:
            return left

        if left.val < right.val:
            result = left
            result.next = self.sortedMerge(left.next, right)
        else:
            result = right
            result.next = self.sortedMerge(left, right.next)

        return result

    def getMiddle(self, head: ListNode) -> ListNode:
        if head == None:
            return None

        slow = head
        fast = head.next

        while (fast != None):
            fast = fast.next
            if (fast != None):
                slow = slow.next
                fast = fast.next

        return slow

测试样例

我们使用下面这个测试样例进行测试:

headA = ListNode(1)
headA.next = ListNode(2)
headA.next.next = ListNode(3)
headA.next.next.next = ListNode(4)
headA.next.next.next.next = ListNode(5)

headB = ListNode(6)
headB.next = ListNode(7)
headB.next.next = ListNode(8)
headB.next.next.next = headA.next.next.next

solution = Solution()
result = solution.getIntersectionNode(headA, headB)
print(result.val)

输出结果为:

4
总结

本文介绍了如何用合并排序的方式解决求两个链表的相交点问题。不同于其他方法,这种方法对两个链表进行了排序,然后再按照顺序寻找相交点,比较直观易懂,也比较容易实现。但需要注意细节,在链表操作时要注意指针相关的问题。