链表--复制含有随机指针节点的链表(leetcode138 题目描述 解法1:使用一个HashMap 解法2:不需要哈希表,只用有限的几个变量完成

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

要求返回这个链表的 深拷贝。

我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

解法1:使用一个HashMap

新建一个key和v都是Node的HashMap,先遍历一次原链表,遍历的过程将原来的节点作为key,根据val新建一个Node作为v。第一次遍历完成后,依次生成了next和ran都为null的只有值的节点。

再次从头遍历原链表,get到原链表节点对应的v,将这个v的next指针和rand指针都指到对应的位置,最后返回map.get(head)

需要遍历两次链表,时间复杂度为O(n),空间复杂度为O(n)

代码:

/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/

class Solution {
    public Node copyRandomList(Node head) {
        Map<Node, Node> map = new HashMap<Node, Node> ();
        Node temp = head;
        while (temp != null){
            map.put(temp, new Node(temp.val));
            temp = temp.next;
        }
        temp = head;
        while (temp != null) {
            map.get(temp).next = map.get(temp.next);
            map.get(temp).random = map.get(temp.random);
            temp = temp.next;
        }

        return map.get(head);
    }
}

解法2:不需要哈希表,只用有限的几个变量完成

链表--复制含有随机指针节点的链表(leetcode138
题目描述
解法1:使用一个HashMap
解法2:不需要哈希表,只用有限的几个变量完成

总结来说:

(1)在后面新建节点

(2)新建节点的rand指到原来的rand的下一个:本题的痛点就在于不容易找到rand,本解法巧妙地解决了这个问题

(3)分离

时:O(n)

空:O(1)

代码:

    public Node copyRandomList1(Node head){
        if (head == null){
            return null;
        }

        Node temp = head;
        //在后面新建
        while (temp != null) {
            Node tempNext = temp.next;
            temp.next = new Node(temp.val);
            temp.next.next = tempNext;
            temp = temp.next.next;
        }
        temp = head;
        //复制rand指针
        while (temp != null) {
            Node curr = temp.next;
            curr.random = temp.random != null ? temp.random.next : null;
            temp = temp.next.next;
        }
        Node dummy = new Node(-1);
        Node newTemp = dummy;
        temp = head;
        //拆分
        while (temp != null){
            newTemp.next = temp.next;
            newTemp = newTemp.next;
            temp.next = temp.next.next;
            temp = temp.next;
        }
        newTemp.next = null;

        return dummy.next;
    }