LeetCode Intersection of Two Linked Lists

LeetCode解题之Intersection of Two Linked Lists


原题

找出两个单向链表是在哪个节点开始合二为一的。

注意点:

  • 如果没有交集,那么返回None
  • 返回结果时要保证链表还是原来的结构
  • 链表中没有环形结构
  • 最好时间复杂度为O(n),空间复杂度为O(1)

例子:

输入:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

输出: c1

解题思路

最容易想到的方法是双指针,在交点之前,两个链表的长度不同,如果我们知道他们的长度差,那么只要在长的链表上先前进他们相差的节点数,然后两个指针同时各自在两个链表上前进,那么当他们相遇的时候就是第一个相交的节点。而那个差就是两个链表的长度差,因为它们的后半部分是相同的。

上面是通过让长链表上的指针先走的方法,其实我们也可以在链表前加长,使得它们在交点之前的长度相等,在上面的例子中,我们可以在链表A之前加上一个链表B,在链表B之前加上一个链表A,这时两条链表的总长度相同,都是原来两条链表的长度和,那么在它们交点前的链表长度也是相等的。让两个指针同时前进直到相交即可。

还可以通过复用Linked List Cycle II的代码来实现,我们将链表A的尾部连接到它的头部,这道题就变成找出链表中环的起始位置了。不过要记得将链表恢复原样。

AC源码

# Definition for singly-linked list.
class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None


class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        nodeA, nodeB = headA, headB
        while nodeA != nodeB:
            nodeA = nodeA.next if nodeA else headB
            nodeB = nodeB.next if nodeB else headA
        return nodeA

    def getIntersectionNode_diff(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """

        def get_length(node):
            length = 0
            while node:
                node = node.next
                length += 1
            return length

        len1 = get_length(headA)
        len2 = get_length(headB)
        if len1 > len2:
            for __ in range(len1 - len2):
                headA = headA.next
        else:
            for __ in range(len2 - len1):
                headB = headB.next
        while headA:
            if headA == headB:
                return headA
            headA = headA.next
            headB = headB.next
        return None


if __name__ == "__main__":
    None

欢迎查看我的Github (https://github.com/gavinfish/LeetCode-Python) 来获得相关源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值