【剑指offer】两个链表的第一个公共节点(Python)

题目描述

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

思路

方法一:两个有公共节点的链表是Y字型的结构,自公共节点后是重合的。可以借助两个栈先存储链表的节点。然后两个栈每次出栈一个节点,如果是重合节点,那么这两个节点是相等的。所以最后一个相等的节点就是第一个公共节点。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        if not pHead1 or not pHead2:
            return None
        stack1 = []
        stack2 = []
        while pHead1:
            stack1.append(pHead1)
            pHead1 = pHead1.next
        while pHead2:
            stack2.append(pHead2)
            pHead2 = pHead2.next
        res = None
        while stack1 and stack2:
            p1 = stack1.pop()
            p2 = stack2.pop()
            if p1 == p2:
                res = p1
            else:
                break
        return res

方法二:先遍历两个链表,统计长度aa 和bb 。让长链表先走|a−b||a−b| 步,公共节点肯定是存在于后面部分中。然后再对两个链表遍历匹配,遇到的第一个相同节点就是公共节点。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        if not pHead1 or not pHead2:
            return None
        l1 = 0
        l2 = 0
        h1 = pHead1  #在计算长度的时候要用一个中间链表来计算,不能改变原链表的值
        h2 = pHead2  #在计算长度的时候要用一个中间链表来计算,不能改变原链表的值
        while h1:
            l1 += 1
            h1 = h1.next
        while h2:
            l2 += 1
            h2 = h2.next
        if l1 > l2:
            for i in range(l1-l2):
                pHead1 = pHead1.next  #这个时候才能改变原链表的值
        elif l1 < l2:
            for i in range(l2-l1):
                pHead2 = pHead2.next
        while pHead1 and pHead2:
            if pHead1 == pHead2:
                return pHead1
            else:
                pHead1 = pHead1.next 
                pHead2 = pHead2.next
        return None

方法三:时间复杂度和上述代码相同,都需要遍历链表(1+公共节点之前的长度/总长度)遍,但短的代码长度,解题思路跟方法二也是一样的,但是更少的变量,更巧妙的代码运用,真的是很厉害啊!

def FindFirstCommonNode(self, pHead1, pHead2):
    p1, p2 = pHead1, pHead2
    while p1 != p2:
        p1 = p1.next if p1 != None else pHead2
        p2 = p2.next if p2 != None else pHead1
    return p1

假设P2首先为None,则P1剩下要走的长度为(L1-L2)

此时P2=pHead1,即等于较长的那个链表,继续跟着P1一起走完(L1-L2),相当于先把pHead1和pHead2之间相差的距离走完

P1走完后,P1=pHead2,这个时候P2和P1剩下的长度相同。(和方法二的思路一样)

猜你喜欢

转载自blog.csdn.net/yingzoe/article/details/88774333