📌  相关文章
📜  在 O(1) 空间中克隆一个带有 next 和随机指针的链表(1)

📅  最后修改于: 2023-12-03 14:51:03.287000             🧑  作者: Mango

在 O(1) 空间中克隆一个带有 next 和随机指针的链表

介绍

在链表中,每个节点都有一个next指针和一个随机指针。next指针指向下一个节点,而随机指针可以指向任意一个节点(包括自己)。现在,我们需要在O(1)空间复杂度的前提下,克隆这个链表。

思路

要求在O(1)空间复杂度的前提下,我们不能使用额外的数据结构来储存链表。但是我们可以在原有的链表上进行一些修改,使得原有的链表中的每个节点都可以储存克隆后的节点的信息。

具体来说,我们可以在原有的每个节点后面插入一个新的节点,新节点的值为原有节点的值,然后将新节点插入到原有节点的next指向的节点的前面。插入完成后,我们可以将原有节点的随机指针指向的节点的next指针复制给新节点的随机指针。

这样,我们就可以将克隆后的节点信息储存在原有节点的next指针指向的节点中,而不会使用额外的空间储存,并且可以保持原有的链表结构不变。

最后,我们只需要将原有链表和克隆链表中的节点依次链接即可。注意需要在链接完成后,将原有链表中的节点和克隆链表中的节点分开。

代码
function cloneLinkedList(head) {
  if (!head) return null;

  // 遍历原有链表,在每个节点后面插入一个新节点
  let node = head;
  while (node) {
    const newNode = new Node(node.val);
    newNode.next = node.next;
    node.next = newNode;
    node = newNode.next;
  }

  // 复制随机指针
  node = head;
  while (node) {
    if (node.random) {
      node.next.random = node.random.next;
    }
    node = node.next.next;
  }

  // 将原有链表和克隆链表断开
  node = head.next;
  let prev = head;
  const cloneHead = head.next;
  while (node.next) {
    prev.next = node.next;
    prev = node;
    node = node.next;
  }
  prev.next = null;

  return cloneHead;
}

以上是在JavaScript中实现的代码,其中Node代表了链表中的一个节点,val代表节点的值,next和random分别是指向下一个节点和随机节点的指针。

总结

在O(1)空间复杂度的前提下,我们可以通过对原有链表的修改来储存克隆后的节点信息。由于链表中存在随机指针,需要注意复制随机指针的问题。最后,一定要记得将原有链表和克隆链表断开并返回克隆链表的头节点。