python 相交的链表(链表无环的情况)

本文详细介绍了在没有环的情况下判断两个链表是否相交并找到相交节点的四种方法:求长度法、首尾相连法、栈方法和地址哈希法。每种方法都有其独特思路,例如求长度法通过比较链表长度差来调整起始位置,首尾相连法通过双指针首尾交替遍历,栈方法借助栈来比较链表节点,地址哈希法利用Python的内存地址来判断节点是否相同。代码示例展示了每种方法的具体实现。
摘要由CSDN通过智能技术生成

如果两个链表都没有环,那么是否相交只有两种情况:

相交的情况:

不相交的情况:

因为相交的链表的末尾部分是完全相同的,所以这里提供4个思路去求解:

  1. 求长度法:先求出两个链表的长度(如长度为3和4),然后令较长的链表先走4-3=1步。之后两个链表同时向右遍历,如果找到共同的节点,则是第一个相交节点。
  2. 首尾相连法:两个链表同时向右遍历,
    1. 指针p:从A链表头部遍历至末尾时,从B链表头部继续遍历。
    2. 指针q:从B链表头部遍历至末尾时,从A链表头部继续遍历。
    3. 最后p,q指针一定相等,要么是相交节点,要么是None。
  3. 栈方法:将两个链表分别入栈a和b。比较a,b两个栈的栈顶是否相同即可。若相同,则两个栈同时出栈,直到找到不相同的栈顶元素为止。空间复杂度O(m+n)
  4. 地址哈希法。对于python来说,集合元素的查找是O(1),因此在遍历A链表时,将a的元素地址入集合。遍历B链表,查找地址是否在集合内即可。空间复杂度O(m+n)

相关代码如下:

# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
def printNode(node):
    if node:
        print(node.val)
    else:
        print(node)
def getIntersectionNode1(headA: ListNode, headB: ListNode) -> ListNode:
    #求长度方法:
    l1,l2=0,0
    p,q=headA,headB
    while p!=None:  #求长度
        l1+=1
        p=p.next
    while q!=None:
        l2+=1
        q=q.next
    p,q=headA,headB
    if(l1>l2):      #先走几步
        for i in range(l1-l2):
            p=p.next
    else:
        for i in range(l2-l1):
            q=q.next
    while p!=q:     #从头遍历
        p=p.next
        q=q.next
    return q

def getIntersectionNode2(headA: ListNode, headB: ListNode) -> ListNode:
    #首尾相连法:
    p,q=headA,headB
    while p!=q:
        if p == None:
            p = headB
        else:
            p = p.next
        if q == None:
            q = headA
        else:
            q = q.next
    return q

def getIntersectionNode3(headA: ListNode, headB: ListNode) -> ListNode:
    #栈方法:空间复杂度O(m+n)
    dict1 = []
    dict2 = []
    p,q=headA,headB
    while p!=None:      #入栈
        dict1.append(p)
        p=p.next
    while q!=None:
        dict2.append(q)
        q=q.next
    i=-1
    if dict1[i]==dict2[i]:  
        while True:
            if dict1[i]==dict2[i]:
                i-=1
            else:
                return dict1[i+1]
    else:
        return None

def getIntersectionNode4(headA: ListNode, headB: ListNode) -> ListNode:
    #地址哈希法
    p,q=headA,headB
    dict1 = set()           #设置一个集合
    while p!=None:
        dict1.add(id(p))
        p=p.next
    while q!=None:
        if id(q) in dict1:  #id()方法取对象的内存
            return q
        q=q.next
    return None
#样例一:1-2-3   4-5-6
# a1 = ListNode(1)
# a2 = ListNode(2)
# a3 = ListNode(3)
# a4 = ListNode(4)
# a5 = ListNode(5)
# a6 = ListNode(6)
# a1.next = a2
# a2.next = a3
# a4.next = a5
# a5.next = a6
# t = getIntersectionNode1(a1,a4)
# t = getIntersectionNode2(a1,a4)
# t = getIntersectionNode3(a1,a4)
# t = getIntersectionNode4(a1,a4)
# printNode(t)
#样例二:1-2-3    4-2
# a1.next = a2
# a2.next = a3
# a4.next = a2
# t = getIntersectionNode1(a1,a4)
# t = getIntersectionNode2(a1,a4)
# t = getIntersectionNode3(a1,a4)
# t = getIntersectionNode4(a1,a4)
# printNode(t)

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值