java_basic_copyListWithRand

// 【问题】复制含有随机指针节点的链表
// 【问题描述】有一种特殊的链表节点类描述如下:
//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的思路来做,使用了哈希表,使用了额外空间,进行拷贝:
//0)定义这个特殊的链表结构
//1)第一次遍历原始链表 -> value:用HashMap结构复制节点值:Key为Node节点1,Value为拷贝的Node
//2)第二次遍历原始链表:-> next指针 + rand指针复制: 
//	因为1的next指针能够找到2, 2通过哈希表可以找到2’, 所以1’的next指针连接2’,
//	因为1的next指针能够找到3, 3可以通过哈希表找到3’,所以让1’的rand指针连接3’
//	遍历2的过程重复以上操作
//	最终返回1’

【代码】


public class Copy_List_With_Random {
	
	public static class Node{
		private int value;
		private Node next;
		private Node rand;
		public Node(int data) {
			this.value = data;
		}
	}
	
	//【方法一: 使用额外空间HashMap表】
	//自己定义的函数,最后返回一个Node节点,后面是定义的名字及需要传入的参数,O(N),装进去N个数
	public static Node copyListWithRand1(Node head) {
		HashMap<Node, Node> map = new HashMap<>(); // 建立一个哈希表
		Node cur = head; // 建立cur,指针指向链表的头
		// 第一次遍历链表,map,原来的节点与复制节点
		while (cur != null) {
			map.put(cur, new Node(cur.value)); // 建立哈希表,里面放入2个节点Node
			cur = cur.next; 
		}
		// 第二次遍历链表, 设置拷贝后的节点的next指针与rand指针
		cur = head;
		while(cur != null) {
			map.get(cur).next = map.get(cur.next);// 1节点对应的哈希表值为1’节点 的next指针 = (2’节点)1号节点的next为2号,2号的哈希表值为2’节点
			map.get(cur).rand = map.get(cur.rand);
			cur = cur.next;
		}
		return map.get(head); 
	}
	
	//【方法二:直接把复制的节点放在原来的后面(插入),修改指针指向, 不使用额外空间,仅仅使用几个变量】
	public static Node copyListWithRand2(Node head) {
		if (head == null) {
			return null;
		}
		Node cur = head;
		Node next = null;
		//把复制的Node插入到原来的链表中,省去了哈希表的空间
		while(cur != null) {
			next = cur.next; // 原来第二个节点给next
			cur.next = new Node(cur.value);
			cur.next.next = next;
			cur = next;
		}
		cur = head;
		Node curcopy = null;
		// 节点插入后,设置复制节点的指针
		while (cur!= null) {
			next = cur.next.next;
			curcopy = cur.next;
			curcopy.rand = cur.rand != null ? cur.rand.next : null;
			cur = next;
		}
		Node res = head.next;
		cur = head;
		// 把这两部分分开split
		while (cur != null) {
			next = cur.next.next;
			curcopy = cur.next;
			cur.next = next;
			curcopy.next = next != null ? next.next : null;
			
		}
		return res;
	
	}
	
	public static void printRandLinkedList(Node head) {
		Node cur = head;
		System.out.print("order: ");
		while (cur != null) {
			System.out.print(cur.value + " ");
			cur = cur.next;
		}
		System.out.println();
		cur = head;
		System.out.print("rand:  ");
		while (cur != null) {
			System.out.print(cur.rand == null ? "- " : cur.rand.value + " ");
			cur = cur.next;
		}
		System.out.println();
	}
	
	 
	
	public static void main(String[] args) {
		Node head = null;
		Node res1 = null;
		Node res2 = null;
		printRandLinkedList(head);
		res1 = copyListWithRand1(head);
		printRandLinkedList(res1);
		res2 = copyListWithRand2(head);
		printRandLinkedList(res2);
		printRandLinkedList(head);
		System.out.println("=========================");

		head = new Node(1);
		head.next = new Node(2);
		head.next.next = new Node(3);
		head.next.next.next = new Node(4);
		head.next.next.next.next = new Node(5);
		head.next.next.next.next.next = new Node(6);

		head.rand = head.next.next.next.next.next; // 1 -> 6
		head.next.rand = head.next.next.next.next.next; // 2 -> 6
		head.next.next.rand = head.next.next.next.next; // 3 -> 5
		head.next.next.next.rand = head.next.next; // 4 -> 3
		head.next.next.next.next.rand = null; // 5 -> null
		head.next.next.next.next.next.rand = head.next.next.next; // 6 -> 4

		printRandLinkedList(head);
		res1 = copyListWithRand1(head);
		printRandLinkedList(res1);
		res2 = copyListWithRand2(head);
		printRandLinkedList(res2);
		printRandLinkedList(head);
		System.out.println("=========================");

	}

}

【运行结果】

order: 
rand:  
order: 
rand:  
order: 
rand:  
order: 
rand:  
=========================
order: 1 2 3 4 5 6 
rand:  6 6 5 3 - 4 
order: 1 2 3 4 5 6 
rand:  6 6 5 3 - 4 
Exception in thread "main" java.lang.NullPointerException
	at Copy_List_With_Random$Node.access$1(Copy_List_With_Random.java:32)
	at Copy_List_With_Random.copyListWithRand2(Copy_List_With_Random.java:86)
	at Copy_List_With_Random.main(Copy_List_With_Random.java:144)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
amqp_basic_qos是AMQP(Advanced Message Queuing Protocol,高级消息队列协议)的一个方法,它用于在消费者和消息代理(broker)之间设置消息传输的质量保证。 在消息队列中,消费者可以以不同的速率接收消息。如果消费者的处理能力不足,消息可能会积压在队列中,导致系统性能降低或者消息丢失。为了解决这个问题,amqp_basic_qos方法被引入。 amqp_basic_qos方法的作用是告诉消息代理,消费者希望以怎样的速率接收消息。它接收三个参数:prefetch_size、prefetch_count和global。 prefetch_size表示消息大小的预获取限制,如果设置为0,则表示没有大小的限制。 prefetch_count表示消息数量的预获取限制,它指定了消费者可以预先获取的最大消息数量。例如,设置为1表示每次只获取一条消息。 global表示指定是否将预获取限制应用于整个连接,如果设置为false,则表示只对当前消费者进行限制。 通过使用amqp_basic_qos方法,消费者可以根据自身的处理能力和系统负载情况来控制消息接收的速率,避免消息积压和系统过载的问题。同时,amqp_basic_qos方法的使用还可以提高消息处理的效率和质量,保证系统的稳定性。 总之,amqp_basic_qos是AMQP协议中用于设置消息传输质量保证的方法。通过它,消费者可以设置自身获取消息的速率,避免因为消息积压导致的系统性能下降或者消息丢失的问题。同时,amqp_basic_qos方法的使用还可以提高消息处理的效率和质量,保证系统的稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值