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;
        }
    
  • 相关阅读:
    搭建 Linux 下 GitLab 服务器(转)
    sql语法:inner join on, left join on, right join on具体用法
    Android Studio之同一应用创建多个Activity(一)
    java环境变量配置
    老鸟的Python新手教程
    域名注冊以及域名解析设置
    Android在WebView上构建Web应用程序
    利用JasperReport+iReport进行Web报表开发
    android App Widgets
    多数据库下activiti的流程定义缓存问题
  • 原文地址:https://www.cnblogs.com/swifthao/p/13170056.html
Copyright © 2011-2022 走看看