【链表】LeetCode138.复制带随机指针的链表

201 阅读1分钟

题目分析

  • 原题目内容太长,我们简单分析下主要题意
  • 有一个长度为n的链表,每个节点除了有next指针,还有一个随即指针random
  • 我们需要复制这个链表,这个新链表的指针指向必须与原链表的指针指向相同

示例

e1.png

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

哈希表实现

主要思路

  1. 遍历链表,复制每一个节点组成新链表,并将原链表节点和对应的新节点加入到Map中
  2. 然后再次遍历原链表,如果原链表节点随机指针不为空时
  3. 从Map中获取原链表节点随机指针对应的新链表节点
  4. 将新链表节点的随机指针指向对应的节点

代码实现

    public Node copyRandomList(Node head) {
        if(head == null){
            return null;
        }
        Map<Node,Node> map = new HashMap<>();
        Node dummty = new Node(-1);
        Node tail = dummty;
        Node cur = head;
        while(cur != null){
            Node temp = new Node(cur.val);
            map.put(cur,temp);
            tail.next = temp;
            tail = tail.next;
            cur = cur.next;
        }
        tail = dummty.next;
        while(head != null){
            if(head.random != null){
                tail.random = map.get(head.random);
            }
            tail = tail.next;
            head = head.next;
        }
        return dummty.next;
    }

空间优化

主要思路

  1. 创建虚拟头结点,并指向head
  2. 遍历链表,并复制节点,每个节点指向复制后的节点
  3. 比如1 -> 2 -> 3复制后变为dummty -> 1 -> 1 -> 2 -> 2 -> 3 -> 3
  4. 再次遍历链表,此时head.next是复制后的新节点
  5. 所以 head.next.random = head.random.next
  6. 最后拆分链表

代码实现

 public Node copyRandomList(Node head) {
        if(head == null){
            return null;
        }
        Node dummty = new Node(-1);
        dummty.next = head;
        while(head != null){
            Node temp = new Node(head.val);
            temp.next = head.next;
            head.next = temp;
            head = temp.next;
        }
        head = dummty.next;
        while(head != null){
            if(head.random != null){
                head.next.random = head.random.next;
            }
            head = head.next.next;
        }
        head = dummty.next;
        Node res = head.next;
        while(head != null){
            Node t = head.next;
            if(head.next != null){
                 head.next = head.next.next;
            }
            head = t;
        }
        return res;
    }