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

简介: 138_复制带随机指针的链表

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

 

package 链表;
import java.util.HashMap;
import java.util.Map;
public class _138_复制带随机指针的链表 {
    class Node {
        int val;
        Node next;
        Node random;
        public Node(int val) {
            this.val = val;
            this.next = null;
            this.random = null;
        }
    }
    //方法一:使用递归+ hashMap (因为随机指针:一个节点可能被多个其他节点指向)
    /** hashMpa 避免重复创建 **/
    /**
     * ,当我们拷贝节点时,「当前节点的随机指针指向的节点」可能还没创建,因此我们需要变换思路。一个可行方案是,我们利用回溯的方式,让每个节点的拷贝操作相互独立。
     */
    Map<Node, Node> cachedNode = new HashMap<Node, Node>();
    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        if (!cachedNode.containsKey(head)) {
            Node headNew = new Node(head.val);
            cachedNode.put(head, headNew);
            headNew.next = copyRandomList(head.next);
            headNew.random = copyRandomList(head.random);
        }
        return cachedNode.get(head);
    }
    /**
     * 间隔插秧法啦(把秧苗插进来后,以前是走一步,现在多了一个结点要多走一步)
     * 第一步:插入苗
     * 第二步:先处理随机指针的复制(原本有随机、next的复制都需要处理?):优先处理随机(之所以要把苗插入,就是为了实现在同一流水线具有同一规则,如果先处理next 导致已经变成两条链表了,拿不到随机了)
     * @author Huangyujun
     *
     */
    class Solution2 {
        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;
            }
            //第二步:先处理随机指针的复制(利用的是原来的链表非常方便的找到随机,而插入的苗的随机就是在原来的基础+1 【node.random.next】)
            for (Node node = head; node != null; node = node.next.next) {
                Node nodeNew = node.next;
                nodeNew.random = (node.random != null) ? node.random.next : null;
            }
            //第三步:处理next 指针的复制
            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;
        }
    }
}



目录
相关文章
|
1天前
|
算法
LeetCode刷题---21.合并两个有序链表(双指针)
LeetCode刷题---21.合并两个有序链表(双指针)
|
1天前
教你三指针拿捏链表翻转
教你三指针拿捏链表翻转
|
1天前
数据结构--链表刷题(一)快慢指针(下)
数据结构--链表刷题(一)快慢指针
15 0
|
1天前
数据结构--链表刷题(一)快慢指针(上)
数据结构--链表刷题(一)快慢指针
16 0
|
1天前
|
算法 C语言 索引
环形链表(快慢指针)
环形链表(快慢指针)
|
1天前
|
存储 编译器 C语言
【数据结构】深入浅出理解链表中二级指针的应用
【数据结构】深入浅出理解链表中二级指针的应用
32 0
|
1天前
|
算法 Java
快慢指针该如何操作?本文带你认识快慢指针常见的三种用法及在链表中的实战
快慢指针该如何操作?本文带你认识快慢指针常见的三种用法及在链表中的实战
29 0
|
1天前
|
存储 算法
LeetCode刷题--- 61. 旋转链表(快慢指针+闭合为环)
LeetCode刷题--- 61. 旋转链表(快慢指针+闭合为环)
|
1天前
|
算法 索引
LeetCode刷题--- 138. 复制带随机指针的链表(哈希表+迭代)
LeetCode刷题--- 138. 复制带随机指针的链表(哈希表+迭代)
|
1天前
|
算法
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)