返回

重塑LeetCode:巧用Map巧妙复制带随机指针的链表,解题之道尽显

前端

导言:LeetCode 138——复制带随机指针的链表

LeetCode 138号问题要求我们复制一个带有随机指针的链表。这是一道中级难度的算法题,需要我们具备扎实的链表操作基础和巧妙的思维能力。

理解题意:随机指针的含义

与普通链表不同,带有随机指针的链表中,每个节点除了指向下一个节点的指针(next)之外,还有一个随机指针(random)指向链表中的任意节点,甚至指向它自己。复制这样的链表,需要确保新链表中的节点不仅具有相同的值和顺序,而且随机指针也指向正确的位置。

解题思路:借用Map巧妙复制

要解决这个问题,我们可以使用一个Map数据结构。Map是一个键值对集合,其中每个键与一个值相关联。我们利用Map将原链表中的节点作为键,将复制后的节点作为值。

算法步骤:

  1. 构建一个不包含next和random域的链表:

    • 遍历原链表,依次创建新节点,并将其添加到新链表中。
    • 将新节点的val域设置为原节点的val域。
    • 将新节点的next域暂时设置为None。
  2. 让node重新指向Map中的值:

    • 遍历原链表,对于每个节点node:
      • 如果node.random为None,则新节点的random域也设置为None。
      • 否则,从Map中查找以node.random为键的值,并将其设置为新节点的random域。
  3. 返回新链表的头结点。

代码实现:

def copyRandomList(head):
    # 创建一个Map
    node_map = {}

    # 构建一个不包含next和random域的链表
    new_head = Node(head.val)
    node_map[head] = new_head
    curr = new_head
    while head.next:
        head = head.next
        new_node = Node(head.val)
        node_map[head] = new_node
        curr.next = new_node
        curr = curr.next

    # 让node重新指向Map中的值
    curr = new_head
    while curr:
        if head.random:
            curr.random = node_map[head.random]
        head = head.next
        curr = curr.next

    return new_head

算法分析:

这种方法的时间复杂度为O(n),其中n为链表的长度。我们遍历原链表两次,一次创建新链表,一次更新随机指针。空间复杂度也为O(n),因为我们使用了Map来存储节点的对应关系。

总结:

利用Map数据结构,我们可以巧妙地复制带随机指针的链表。这种方法不仅高效,而且易于理解。希望这篇文章能帮助你深入理解这道题目的精髓,在LeetCode的进阶道路上更进一步。