0
点赞
收藏
分享

微信扫一扫

两个链表相交的一系列问题

单链表可能有环,也可能无环。给定两个单链表的头节点 head1 和 head2,这两个链表可能相交,也可能不相交。请实现一个函数,如果两个链表相交,请返回相交的第一个节点;如果不相交,返回null即可。


如果链表 1 的长度为 N,链表 2 的长度为 M,时间复杂度请达到 O(N+M),额外空间复杂度请达到 O(1)




•问题一:判断链表是否有环


• 设置一个慢指针和一个快指针。从链表头结点开始,慢指针一次走一步,
慢指针一次走两步• 如果链表无环,则快指针会移动到终点。

• 如果链表有环,则快指针和慢指针会相遇。相遇后令快指针回到头节点,接着快慢指针都一次走一步,两者再次相遇的节点就是入环节点


def getLoopNode(head):

    if head == None or head.next == None or head.next.next == None:
        return None
    slow = head.next
    fast = head.next.next
    while slow != fast:
        if fast.next == None or fast.next.next == None:
            return None
        slow = slow.next
        fast = fast.next.next
    fast = head
    while slow != fast:
        slow = slow.next
        fast = fast.next
    return slow




•问题二:判断两个无环链表是否相交

• 先分别遍历两个链表,得到两个链表的的长度:len1 和 len2

• 如果链表 1 更长,则链表 1 先走 len1 - len2 步;否则,链表 2 先走 len2 - len1 步

• 然后两个链表一起走,一次走一步,相遇的节点就是相交节点


def noLoop(head1, head2):
    if head1 == None or head2 == None:
        return None
    cur1 = head1
    cur2 = head2
    n = 0
    while cur1.next != None:
        n += 1
        cur1 = cur1.next
    while cur2.next != None :
        n -= 1
        cur2 = cur2.next
    if cur1 != cur2:
        return None 
    cur1 = head1 if n >= 0 else head2
    cur2 = head1 if cur1 == head2 else head2
    n = abs(n)
    while n != 0:
        cur1 = cur1.next 
        n -= 1
    while cur1 != cur2:
        cur1 = cur1.next
        cur2 = cur2.next
    return cur1




•问题三:判断两个有环链表是否相交
• 先得到两个有环链表的入环节点 loopNode1 和 loopNode2
• 如果 loopNode1 == loopNode2,那 么两个链表必然相交(有公共的环), 而且相交节点必然位于入环节点之前 (包含入环节点)。入环之前的链表 部分没有环,所以求相交节点的方法 同问题二,只是将链表终点从 nullptr 换成了 loopNode1->next


如果 loopNode1 != loopNode2,那么两个链表可能相交也可能不相交,相交的情况也只可能发生在环节点中 

从loopNode1开始绕圈遍历节点,再绕回到loopNode1之前如果遇到loopNode2,说明相交,返回 loopNode1或loopNode2都行,都算相交节点。如果绕回loopNode1的过程中一直没碰上loopNode2,说明不相交

 

def bothLoop(head1, node1, head2, node2):
    if head1 == None or head2 == None:
        return None
    if node1 == node2:
        cur1 = head1
        cur2 = head2
        n = 0
        while cur1 != node1:
            n += 1
            cur1 = cur1.next
        while cur2 != node1:
            n -= 1
            cur2 = cur2.next
        cur1 = head1 if n >= 0 else head2
        cur2 = head1 if cur1 == head2 else head2
        n = abs(n)
        while n != 0:
            n -= 1
            cur1 = cur1.next
        while cur1 != cur2:
            cur1 = cur1.next
            cur2 = cur2.next
        return cur1
    else:
        cur1 = node1.next
        while cur1 != node1:
            if cur1 == node2:
                return node1
            cur1 = cur1.next
        return None


#主函数
class Node:
    def __init__(self, val=None):
        self.val = val
        self.next = None

def getIntersectNode(head1, head2):
    if head1 == None or head2 == None:
        return None
    node1 = getLoopNode(head1)
    node2 = getLoopNode(head2)
    if node1 == None and node2 == None:
        return noLoop(head1, head2)
    if node1 != None and node2 != None:
        return bothNode(head1, node1, head2, node2)
    return None
举报

相关推荐

0 条评论