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

72 阅读1分钟

image.png

image.png

image.png

1、这种题首先想到是用哈希表保存每个结点对应的复制结点,然后用递归的方法得到每个复制节点的random域和next域,这种方法是很直观,需要注意每次递归都要判断当前节点是否复制过。

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

2、另一种方法是在原来的链表的每一个结点后面增加它对应的复制结点,然后再把复制后的结点的random域设置成复制后的结点对应的random,最后把复制后的结点与原来的结点分开。

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        for (Node node = head; node != null; node = node.next.next) {
            Node nodeNew = new Node(node.val);
            nodeNew.next = node.next;
            node.next = nodeNew;
        }
        for (Node node = head; node != null; node = node.next.next) {
            Node nodeNew = node.next;
            nodeNew.random = (node.random != null) ? node.random.next : null;
        }
        Node headNew = head.next;
        for (Node node = head; node != null; node = node.next) {
            Node nodeNew = node.next;
            node.next = node.next.next;
            nodeNew.next = (nodeNew.next != null) ? nodeNew.next.next : null;
        }
        return headNew;
    }
}