剑指offer--面试题37:两个链表的第一个公共结点



题目描述

输入两个链表,找出它们的第一个公共结点。
python实现:
# -*- coding:utf-8 -*-
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    # 法1:朴素方法,先求2个链表的长度,假设长度差为k,然后让较长链表先往后走k步
    # 然后是两个链表一起往后走,每走一步就检查一下是否是同一个节点
    # 时间复杂度:O(m+n),求长渡是需要额外遍历一遍
    
    # 法2:假设链表a,b,将b的表尾和表头连接起来形成环,然后从a往后检查,找到相遇点(在环内)
    # 然后a从头走,b从相遇点走,相遇的第一个点就是交点
    # 时间复杂度也是O(m+n)
    
    # 法3:再确保有交点的时候,还可以使用法3,假设p1,p2分别指向短链表和长链表,2个指针一起走,
    # 短的那个先走到终点(p1先到终点),长的那个指针(p2)目前
    # 离终点还差k步(长度差),然后p1指向长的链表头结点L2,2个指针继续走;当原先长的指针p2
    # 走到终点,此时短指针p1也正好走了k步,然后p2重新执行短链表L1,此时2指针是对齐的(从尾部看)
    # 然后一起往后走,会到达交汇点
    
    # 下面使用法1和法3
    # 法1
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        if pHead1 is None or pHead2 is None:
            return None
        len1, len2 = self.getLen(pHead1), self.getLen(pHead2)
        #让head1指向更短的链表
        if len1>len2:
            pHead1, pHead2 = pHead2, pHead1
            len1, len2 = len2, len1
             
        gap = len2-len1
        p1 = pHead1
        p2 = pHead2
        while gap:
            p2 = p2.next
            gap -= 1
         
        while p1:
            if p1!=p2:
                p1=p1.next
                p2=p2.next
            else:
                return p1
        return None
             
         
    def getLen(self, head):
        if head is None:
            return 0
        p = head
        cnt = 0
        while p:
            cnt += 1
            p = p.next
        return cnt


    # 法3:当确保一定有交点时可用此方法
    def FindFirstCommonNode3(self , pHead1 , pHead2 ):
        # write code here
        if pHead1 is None or pHead2 is None:
            return None
        
        p1, p2 = pHead1, pHead2
        while p1 is not  p2:
            p1 = p1.next if p1 else pHead2
            p2 = p2.next if p2 else pHead1
        return p1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值