链表--复制含有随机指针节点的链表

 一种特殊的链表节点类描述如下:

public class Node { public int value; public Node next;
  public Node rand;
  public Node(int data) { this.value = data; }
}

Node类中的value是节点值, next指针和正常单链表中next指针的意义一 样, 都指向下一个节点,

rand指针是Node类中新增的指针, 这个指针可 能指向链表中的任意一个节点, 也可能指向null。

给定一个由Node节点类型组成的无环单链表的头节点head,

请实现一个 函数完成这个链表中所有结构的复制, 并返回复制的新链表的头节点。

 

 

进阶:不使用额外的数据结构, 只用有限几个变量, 且在时间复杂度为 O(N)内完成原问题要实现的函数。

利用HashMap<Node, Node>将head节点均保存进去,key是head的结点,value是相应节点复制的新节点

然后遍历Map,将对应的rand结点找出来相连接

public static Node copyRandom1(Node head){
            if(head == null || head.next == null) return head;
            Map<Node, Node> map = new HashMap<>();
            Node node = head;
            while(node != null){
                map.put(node, new Node(node.val));
                node = node.next;
            }
            node = head;
            while(node != null){
                map.get(node).next = node.next;
                map.get(node).rand = node.rand;
                node = node.next;
            }
            return map.get(head);
        }

  

解法二:将next结点先链接在node结点之后,然后将遍历的时候,将node结点的rand作为线索

然后将node.next的rand找到指向,最后再将两个链表分开即可。

public static Node copyRandom2(Node head){
        if(head == null || head.next == null) return head;
        Node node = head;
        while(node != null){
            Node nextNode = node.next;
            node.next = new Node(node.val);
            node.next.next = nextNode;
            node = nextNode;
        }
        node = head;
        while(node != null){
            node.next.rand = node.rand;
            node = node.next.next;
        }
        node = head;
        Node newHead = node.next;
        while(node != null){
            Node nextNode = node.next.next;
            Node node1 = node.next;
            node.next = nextNode;
            node1.next = nextNode != null ? nextNode.next : null;
            node = nextNode;

        }
        return newHead;
    }

  

posted @ 2018-04-09 11:18  SkyeAngel  阅读(194)  评论(0编辑  收藏  举报