• 每日一题 为了工作 2020 0325 第二十三题


    /**
    *
    * 问题: 复制含有随机指针节点的链表
    *
    * 分析:
    * 给定一个由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+"	");
    				current=current.next;
    			}
    		}else if(tip.equals("rand")) {
    			current=head;
    			while(current!=null) {
    				System.out.print(current.value+"	");
    				current=current.rand;
    			}
    		}
    		System.out.println();
    	}
    }
    

      

    *运行结果

     

  • 相关阅读:
    node.js JS对象和JSON字符串之间的转换
    read和write函数
    使用stdarg.h实现可变长度参数
    PHP __DIR__, __FILE__, __FUNCTION__, __CLASS__, __METHOD__, __LINE__, __NAMESPACE__
    Yii中 RBAC(基于角色的访问控制权限)表结构原理分析
    让服务器apache/iis/nginx支持.apk/ipa文件下载
    jQuery的maskedinput插件 设置input掩码
    修改XCode的Product的输出目录(有时不生效需看)
    OC的类别(分类)和拓展
    C和C++混合编程中的extern "C" {}
  • 原文地址:https://www.cnblogs.com/walxt/p/12565488.html
Copyright © 2020-2023  润新知