138. 复制带随机指针的链表

308 阅读1分钟

题目描述

思路

  • 复制简单单向链表时,可以直接复制。

  • 这个提,对某一个节点来说,要复制两个东西,所以可能会重复复制。比如前面的节点已经复制6作为他的random,恰好当前节点的next也是6,就不能再复制了,应该直接指向之前复制的6.

    • cur.random
    • cur.next
  • 解决方法:用Map<原链表中的节点,新链表中对应位置上的节点>来记录哪些node已经被添加过了,在add cur.next和cur.random前先判断是否已经存在要添加的节点,如果存在,直接get(对应位置上的旧节点),如果不存在再new一个。

方法一 直接复制

IMG_2FA790DDF30F-1.jpeg

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) return head;
        // 复制各个node
        Node cur = head;
        while (cur != null) {
            Node newNode = new Node(cur.val);
            newNode.next = cur.next;
            cur.next = newNode;
            cur = cur.next.next;
        }
        // 复制 random 指针
        cur = head;
        while (cur != null) {
            Node random = cur.random;
            cur.next.random = random == null ? null : random.next;// 
            cur = cur.next.next;
        }
        // disconnect copied with original
        Node newHead = head.next;
        Node cur1 = head, cur2 = newHead; // 
        while (cur1.next != null && cur2.next != null) {
            cur1.next = cur1.next.next; // order
            cur2.next = cur2.next.next; 
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        cur1.next = null; // 画个图
        return newHead;
    }
}

方法二 map

  • map<old, new>
  • 先拷贝一个新的头节点
  • cur1.next.val, cur1.random.val 需要判断一下是否为空
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) {
        if (head == null) {
            return head;
        }
        Node newHead = new Node(head.val);//复制一个新头
        Map<Node, Node> map = new HashMap<>();//map中放<旧节点,新节点>
        map.put(head, newHead);
        Node cur1 = head;//cur1为原链表指针
        Node cur2 = newHead;//cur2为新链表指针
        while (cur1 != null) {
            //当前节点的next节点还没有在新list中被添加过
            if (map.get(cur1.next) == null) {
                Node nxt = cur1.next == null ? null : new Node(cur1.next.val);//注意cur.next=null的情况
                cur2.next = nxt;
                map.put(cur1.next, cur2.next);
            } else {
                cur2.next = map.get(cur1.next);
            }
            //当前节点的random节点还没有在新list中被添加过
            if (map.get(cur1.random) == null) {
                Node rdm = cur1.random == null ? null : new Node(cur1.random.val);//注意cur.next=null的情况
                cur2.random = rdm;
                map.put(cur1.random, cur2.random);
            } else {
                cur2.random = map.get(cur1.random);
            }
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        return newHead;
    }
}