zoukankan      html  css  js  c++  java
  • 链表--复制含有随机指针节点的链表(leetcode138

    题目描述

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

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

    我们用一个由 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:不需要哈希表,只用有限的几个变量完成

    总结来说:

    (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;
        }
    
  • 相关阅读:
    人生的诗·260~264节
    唐诗宋词·151~155节
    人生的诗·270~274节
    人生的诗·265~269节
    人生的诗·255~259节
    唐诗宋词学习·146~150节
    唐诗宋词学习·156~160节
    加载时xml 报 未能映射路径"***.xml"
    我喜欢的语言总结语句
    关于图片延迟的一点思路
  • 原文地址:https://www.cnblogs.com/swifthao/p/13170056.html
Copyright © 2011-2022 走看看