/**
*
* 问题: 复制含有随机指针节点的链表
*
* 分析:
* 给定一个由Node节点类型组成的无环单链表的头节点head, 请实现一个函数完成这
* 个链表中所有结构的复制, 并返回复制的新链表的头节点。例如: 链表1->2->3->null,
* 假设1的 rand指针指向3, 2的 rand指针指向 null, 3的 rand指针指向1。复制后的链
* 表应该也是这种结构, 比如, 1‘->2‘->3‘->null, 1‘的 rand指针指向3‘,2‘的 rand
* 指针指向 null, 3‘的 rand指针指向1‘, 最后返回1‘。
*
* 解答:
*
*1.首先从左到右遍历链表, 对每个节点都复制生成相应的副本节点, 然后将对应关系放入哈希
*表 map中。例如, 链表1->2->3->null, 遍历1、2、3时依次生成1‘、2‘、3‘。 最后将
*对应关系放入map中:
*
*2.再从左到右遍历链表, 此时就可以设置每一个副本节点的 next和 rand指针。例如原链表
*1->2->3->null, 假设1的 rand指针指向3, 2的 rand指针指向null, 3的rand指针
*指向1。遍历到节点1时, 可以从map中得到节点1的副本节点1‘, 节点1的next指向节点2,
*所以从map中得到节点2的副本节点2‘, 然后令1‘.next=2‘, 副本节点1‘的next指针就
*设置好了。同时节点1的rand指向节点3, 所以从map中得到节点3的副本节点3‘, 然后令
*1‘.rand=3‘, 副本节点1的rand指针也设置好了。以这种方式可以设置每一个副本节点的
*next与rand指针。
*
*3.将 1‘节点作为结果返回即可。
*
*哈希表增删改查的操作时间复杂度都是0(1), 普通方法一共只遍历链表两遍, 所以普通解法的
*时间复杂度为O(N), 因为使用了哈希表来保存原节点与副本节点的对应关系, 所以额外空间复杂度为O(N)。
*
* @author 雪瞳
*
*/
*代码
public class Node { public int value; public Node next; public Node rand; public Node(int data) { this.value=data; } }
import java.util.HashMap; import java.util.Map; public class CopyListWithRand { public Node copyList(Node head) { Map<Node, Node> map = new HashMap<Node, Node>(); Node current = head; //复制链表 while(current!=null) { map.put(current, new Node(current.value)); current=current.next; } //更新指针 current = head; while(current!=null){ map.get(current).next=map.get(current.next); map.get(current).rand=map.get(current.rand); current=current.next; } return map.get(head); } }
public class TestCopyListWithRand { public static void main(String[] args) { TestCopyListWithRand test = new TestCopyListWithRand(); CopyListWithRand copy = new CopyListWithRand(); Node head1 = new Node(1); Node head2 = new Node(2); Node head3 = new Node(3); Node head4 = new Node(4); Node copyHead = null; //为方便观察效果将head1都设为头节点 head1.next=head2; head2.next=head3; head3.next=head4; head1.rand=head3; head3.rand=head4; head4.rand=head2; System.out.println("初始状态..."); test.showByTip(head1, "next"); test.showByTip(head1, "rand"); copyHead = copy.copyList(head1); System.out.println("复制后状态..."); test.showByTip(copyHead, "next"); test.showByTip(copyHead, "rand"); } public void showByTip(Node head ,String tip) { Node current = null; System.out.println("链表内的值按照"+tip+"顺序显示如下:..."); if(tip.equals("next")) { current=head; while(current!=null) { System.out.print(current.value+"\t"); current=current.next; } }else if(tip.equals("rand")) { current=head; while(current!=null) { System.out.print(current.value+"\t"); current=current.rand; } } System.out.println(); } }
*运行结果
原文地址:https://www.cnblogs.com/walxt/p/12565488.html