这目录
剑指 Offer 52. 两个链表的第一个公共节点
题目描述
输入两个链表,找出它们的第一个公共节点。
题解
- 先计算长度,再利用双指针相遇
首先我们想到,我们希望两个指针同时出发,然后在交点处相遇是最好的。
我们假设速度是相同的,毫无疑问,我们希望他们起点到交点的长度最好也要相同。
但是两条链表起点到交点的长度并不同,怎么办? 让其中一个指针线先走几步?
走几步?当然是落后多少就先走做少咯,落后的步数不就是两条链表长度之差么。
这样,两个指针就在统一起跑线了,如果他们注定会相遇,那一定会是在交点,如果直到最后都还没相遇,那只能说明他们并没有相交
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
def getLength(head):
# 计算链表长度
length = 0
while head:
length += 1
head = head.next
return length
# 计算长度
lengthA = getLength(headA)
lengthB = getLength(headB)
startA = headA
startB = headB
# 移动指针
if lengthA < lengthB:
for _ in range(lengthB - lengthA):
startB = startB.next
else:
for _ in range(lengthA - lengthB):
startA = startA.next
# 起点即相遇的情况
if startA == startB:
return startA
# 两个指针移动直至相遇
while startA and startB:
if startA.next == startB.next:
return startA.next
startA, startB = startA.next, startB.next
- 快慢指针相遇
这个解法很简单,每个链表其实都由两个部分组成,相交前和相交后
所以链表1的长度我们设置为a + c, 链表二为b + c
怎么保证两个从头结点出发的指针同时到达交点?
让一个指针走 a+c+b步,让另外一个指针走b+c+a步,这样他们就一定会在交点处相遇了
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
start1, start2 = headA, headB
while start1 != start2:
start1 = start1.next if start1 else headB
start2 = start2.next if start2 else headA
return start1
剑指 Offer 35. 复杂链表的复制
题目描述
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
题解
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
if not head:
return None
head1 = head
node_copy = {head1: Node(head1.val)}
while head1:
if head1.next not in node_copy and head1.next:
node_copy[head1.next] = Node(head1.next.val)
if head1.random not in node_copy and head1.random:
node_copy[head1.random] = Node(head1.random.val)
if head1.next:
node_copy[head1].next = node_copy[head1.next]
if head1.random:
node_copy[head1].random = node_copy[head1.random]
head1 = head1.next
return node_copy[head]
创建一个映射:原始点 -》复制的点
然后一个一个复制即可