剑指 Offer 52. 两个链表的第一个公共节点
Posted 炫云云
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 52. 两个链表的第一个公共节点相关的知识,希望对你有一定的参考价值。
剑指 Offer 52. 两个链表的第一个公共节点
输入两个链表,找出它们的第一个公共节点。
如下面的两个链表**:**
在节点 c1 开始相交。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5],listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例 2:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB
可以是任意值。
解释:这两个链表不相交,因此返回 null。
双指针
使用双指针的方法,可以将空间复杂度降至 O ( 1 ) O(1) O(1) 。
只有当链表 head A A A 和 h e a d B h e a d B headB 都不为空时,两个链表才可能相交。因此首先判断链表 h e a d A h e a d A headA 和 head B B B 是否为空, 如果其中至少有一个链表为空,则两个链表一定不相交,返回 null。
当链表 head A A A 和 h e a d B h e a d B headB 都不为空时,创建两个指针 p A p A pA 和 p B p B pB, 初始时分别指向两个链表的头节点 head A A A 和 h e a d B h e a d B headB, 然后将两个指针依次谝历两个链表的每个节点。具体做法如下:
- 每步操作需要同时更新指针 p A p A pA 和 p B 。 p B_{\\text {。 }} pB。
- 如果指针 p A p A pA 不为空,则将指针 p A p A pA 移到下一个节点; 如果指针 p B p B pB 不为空,则将指针 p B p B pB 移到 下一个节点。
- 如果指针 p A p A pA 为空,则将指针 p A p A pA 移到链表 h e a d B h e a d B headB 的头节点; 如果指针 p B p B pB 为空,则将指针 p B p B pB 移到链表 h e a d A h e a d A headA 的头节点。
- 当指针 p A p A pA 和 p B p B pB 指向同一个节点或者都为空时,返回它们指向的节点或者 null。
证明
# 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
"""
if not headA or not headB:
return None
curA,curB = headA,headB
while curA !=curB:
curA = curA.next if curA else headB
curB = curB.next if curB else headA
return curA
差值解法
先对两条链表扫描一遍,取得两者长度,然后让长的链表先走「两者的长度差值」,然后再同时走,遇到第一个节点即是答案。
# 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
"""
def length(L):
n = 0
while L:
n += 1; L = L.next
return n
len1, len2 = length(headA), length(headB)
if len1 > len2:
headA, headB = headB, headA
for _ in range(abs(len1 - len2)):
headB = headB.next
while headA and headB and headA is not headB:
headA, headB = headA.next, headB.next
return headA
参考
以上是关于剑指 Offer 52. 两个链表的第一个公共节点的主要内容,如果未能解决你的问题,请参考以下文章