剑指 Offer #35 #52 链表,双指针,遍历

剑指 Offer 52. 两个链表的第一个公共节点

题目描述

输入两个链表,找出它们的第一个公共节点。

题解

  1. 先计算长度,再利用双指针相遇

首先我们想到,我们希望两个指针同时出发,然后在交点处相遇是最好的。

我们假设速度是相同的,毫无疑问,我们希望他们起点到交点的长度最好也要相同。

但是两条链表起点到交点的长度并不同,怎么办? 让其中一个指针线先走几步?

走几步?当然是落后多少就先走做少咯,落后的步数不就是两条链表长度之差么。

这样,两个指针就在统一起跑线了,如果他们注定会相遇,那一定会是在交点,如果直到最后都还没相遇,那只能说明他们并没有相交

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. 快慢指针相遇

这个解法很简单,每个链表其实都由两个部分组成,相交前和相交后

所以链表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]

创建一个映射:原始点 -》复制的点

然后一个一个复制即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值