《剑指offer》47、两链表的首个公共结点

offer47的要求很简单:输入两个链表,找出它们的第一个公共结点。
又先搬一张图,最近画图很懒啊……

二次遍历

方法有很多,除了暴力方法外,我最先想到的是二次遍历:先获得两个链表的长度,然后在较长的链表上先走若干步(两链表长度之差),接着同时在两个链表上遍历,找到的第一个相同的节点就是他们的第一个公共节点。时间复杂度O(m + n)。

# offer47-solution 1
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        length1 = self.GetLength(pHead1)
        length2 = self.GetLength(pHead2)

        if length1 > length2:
            headLong = pHead1
            headShort = pHead2
        else:
            headLong = pHead2
            headShort = pHead1
        diff = abs(length1 - length2)

        for i in range(diff):
            headLong = headLong.next  # 长链表的指针先走

        while headLong != None and headShort != None and headLong != headShort: # 没到尾,也没相同,接着走
            headLong = headLong.next
            headShort = headShort.next
        return headLong

    def GetLength(self, pHead):  # 先遍历一次求长度
        length = 0
        while pHead:
            pHead = pHead.next
            length += 1
        return length

玄学

以下是一段通过二次遍历改造的玄学代码,请读者回去自行研究哈哈哈哈哈。

# offer47-solution 2
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

辅助栈

辅助栈的方法,见参考链接:
【剑指offer】37. 两个链表的第一个公共节点(python)
同样是遍历两个链表,将节点保存到栈中。然后利用栈先进后出的特点找到公共节点。

# offer47-solution 3
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        while 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
        commonNode = None
        while stack2 and stack1:
            node1 = stack1.pop()
            node2 = stack2.pop()
            if node1 != node2:
                break
            else:
                commonNode = node1
        return commonNode

个人还是觉得常规的二次遍历好想好写,但是方法3有助于加强栈的运用的熟练性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值