如上图所示,单链表A和单链表B存在相交点C1,C1结点即为单链表A和单链表B的公共子节点
思考:
1. 两个链表会不会存在多个公共子节点?
A:会,C1,C2,C3都是公共子节点;C1可以被认为是交叉节点,交叉节点只有一个
2. 两个双链表会有公共子节点吗?
A:不会,双链表的定义决定的,双链表节点的pre指向是明确的(只有一个)
直接按照题意来,两层循环,类似冒泡排序法,将链表A中的每一个结点依次与链表B中的节点进行比较,如果相等即为公共节点。时间复杂度高
将链表A中元素全部存到Map/集合里,然后遍历链表B中元素,是否在Map/集合中
链表A和链表B,后半部分公共节点是一致的。先将两个链表分别压栈,然后同时出栈,比较出栈元素,最后一组出栈相同的元素即为第一个公共节点
A+B 与 B+A
若链表A和链表B存在公共节点,则 right_a == right_b,且拼接后 A+B 与B+A 的长度是相同的
链表A和链表B长度可能不一致,获取两个链表的长度差 | lengthA - lengthB |,可以考虑先让较长的链表先走 | lengthA - lengthB | 步,然后借用双指针,比较链表A和链表B的结点,找出公共结点
# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
s = set()
node1, node2 = headA, headB
while node1:
s.add(node1)
node1 = node1.next
while node2:
if node2 in s:
break
node2 = node2.next
return node2
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
s1, s2 = [], []
node1, node2 = headA, headB
while node1:
s1.append(node1)
node1 = node1.next
while node2:
s2.append(node2)
node2 = node2.next
c_node = None
i, j = len(s1)-1, len(s2)-1
while i>=0 and j>=0 and s1[i]==s2[j]:
c_node = s1[i]
i -= 1
j -= 1
return c_node
# 容易忽略的一种情况 headA=[1] headB=[1]
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
node1, node2 = headA, headB
while node1 != node2:
node1 = node1.next if node1 else headB
node2 = node2.next if node2 else headA
return node1
注:如果没有公共子结点,就会返回None,链表的最后一个节点为None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
len_a, len_b = 0, 0
node1, node2 = headA, headB
while node1:
len_a += 1
node1 = node1.next
while node2:
len_b += 1
node2 = node2.next
node1, node2 = headA, headB
for i in range(len_a - len_b):
node1 = node1.next
for i in range(len_b - len_a):
node2 = node2.next
while node1 and node2 and node1 != node2:
node1 = node1.next
node2 = node2.next
return node1