剑指offer:Python 两个链表的第一个公共结点 图解 多种解法和解题思路

题目描述

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

思路和Python实现

思路一:粗暴法:用 set() 或者 dic() 这类用了hash表的,空间占用会比较大(不建议这样做)

class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        res_set = set()
        while pHead1:
            res_set.add(pHead1)
            pHead1 = pHead1.next
        while pHead2:
            if pHead2 in res_set:
                return pHead2
            pHead2 = pHead2.next

思路二:先找出两个链表的长度差值,让长的先走差值,然后当两者会合时的结点就是公共结点

图2-1
在这里插入图片描述

class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        if pHead1 == pHead2:
            return pHead1
        len1 = self.get_chain_len(pHead1)
        len2 = self.get_chain_len(pHead2)
        if len2 > len1:  # 哪个长就调换一下顺序
            pHead1, pHead2 = pHead2, pHead1
        diff = abs(len1 - len2)  # 计算差值
        while diff > 0:  # 让长的链表先走diff步
            pHead1 = pHead1.next  # 始终用PHead1 来走,上面比较,会找出较长的一个
            diff -= 1
        while pHead1 != pHead2:
            pHead1 = pHead1.next
            pHead2 = pHead2.next
        return pHead1

    def get_chain_len(self, Head):
        chain_en = 0
        while Head:
            chain_en += 1
            Head = Head.next
        return chain_en

思路三:从尾部向前遍历,找到“最后一个”相同的节点,输出即可。可以利用两个栈来实现

class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        if pHead1== None or pHead2 == None:
            return None
        stack1 = []
        stack2 = []
        p1 = pHead1
        while p1 is not None:   # 依次将两个链表的所有节点分别压入两个栈中
            stack1.append(p1)
            p1 = p1.next
        p2 = pHead2
        while p2 is not None:
            stack2.append(p2)
            p2 = p2.next
        res = None
        while len(stack1) > 0 and len(stack2) > 0:
        # 从后往前遍历,直到找到两个链表相同的最后一个节点,如果相同的话。
            v1 = stack1.pop()
            v2 = stack2.pop()
            if v1 == v2:
                res = v1
            else:
                break
        return res

思路四:再次相遇

  • 两个长度不一样的链表 p1 和 p2 (假设 p1更短,p2更长);p1、p2 先不断的各自的往尾结点移动,短的 p1 先指向None,此时让它再次指向长的链表 p2 开头,和还没走完的长链表 p2 同时继续移动,当长链表 p2 指向None时,让它指向短链表p1的开头;不要忘了,短链表在长链表上已经移动了p2-p1 (两者之间的差)的距离,p2 的起始点变成了短链表的起始点,p1在长链表的起始点,已经和短链表的长度一致,所以 p1 p2 一起移动时,再次相遇就是 第一个公共结点了!
  • 详细过程 见下图 2-2
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        if not pHead1 or not pHead2:
            return None
        p1 = pHead1 # 新起两个指针,不能把原链表的头部丢失掉
        p2 = pHead2
        while p1 != p2:
            p1 = p1.next if p1 is not None else pHead2 # 当前节点为空,指向另一个链表的头部
            p2 = p2.next if p2 is not None else pHead1
        return p1

图 2-2
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值