复制含有随机指针节点的链表~哈希表的使用~(⌒▽⌒)


题目意思就是说给你给head 的Node节点(这是一个比较特殊的链表),来拷贝出它地结构出来。

方法一:借助HashMap的特性,定义一个HashMap<Node,Node> map对象,key和value都是value类型 ,key来存旧的链表,value来存新的链表。最后利用老节点和新节点的对应关系来实现一个拷贝新的链表。

对于理解哈希表的同学来说,应该不难理解,code也比较容易:

/* 方法一:借助HashMap,定义一个HashMap<Node,Node> map对象,key和value都是value类型 */
public static Node copyListWithRandom1(Node head) {
HashMap<Node, Node> map = new HashMap<Node, Node>();
Node cur = head;
/* 将单链表的所有节点和value对应放进去map对象中 */
while (cur != null) {
map.put(cur, new Node(cur.value));// 这里新建一个节点,这个节点放head的value
cur = cur.next;
}
/* 重新构建链表的结构,注意,此时map对象为map<cur,cur'>,cur'为新建立的节点 */
cur = head;
/*
* 为了让大家更好的理解,我们假设旧节点和旧节点的next还有旧节点rand分别为cur,curJiu,curRand
* (不懂的同学可以先去了解一下hashMap特点)所以有:cur.next= curJiu,cur.rand= curRand
* 因此,为了保持这种结构,就有了(map.get(cur)).next = map.get(cur.next),rand同理。
*/
while (cur != null) {
map.get(cur).next = map.get(cur.next);
map.get(cur).rand = map.get(cur.rand);
cur = cur.next;
}
return map.get(head);

}


方法2:空间复杂度为O(1),只需要几个变量就可以实现,(不过个人觉得还是方法1更方便)不多说了,直接附上图:

编程如下:

/*这个方法空间复杂度为O(1),并且不用用到哈希表,相对来说容易了许多,不过思路比较巧妙,主要就是三步走*/
public static Node copyListWithRandom2(Node head) {
if (head == null) {
return null;
}
/* copy node and link to every node*/
/*从之前的1 2 3 4 5 6
*     6 6 5 3 - 4
* 变为现在的1 1 2 2 3 3 4 4 5 5 6 6 
*  6 - 6 - 5 - 3 - - - 4 -
* 说到底就是添加了next指针,而rand指针不变*/
Node next = null;
Node cur = head; //每个新的操作之前都要对cur赋值
while (cur != null) {
next = cur.next; //先保存这个节点,同时也为了下面的移动方便
cur.next = new Node(cur.value);
cur.next.next = next;
cur = next;//这里千万要注意,它要往前移动
}

/*set copy node rand
* 也就是根据rand来设置新的链表的rand指针
* 从之前的1 2 3 4 5 6
*       6 6 5 3 - 4
* 变为现在的1 1 2 2 3 3 4 4 5 5 6 6 
*  6 6 6 6 5 5 3 3 - - 4 4
* 说到底就是添加了rand指针*/
cur = head; //每个新的操作之前都要对cur赋值
Node curcopy = null;
while (cur != null) {
curcopy = cur.next;
/*这里要先判断cur.rand存不存在*/
if (cur.rand != null) {
curcopy.rand = cur.rand.next;
}
next = cur.next.next;
cur = next; //这里千万要注意,它要往前移动
}

/*split,将新建的链表和旧链表分离
* 断开新链表和旧链表的连接*/
cur = head; //每个新的操作之前都要对cur赋值
Node res = head.next;  //定义这个节点是为了方便返回
while (cur != null) {
next = cur.next.next;  
curcopy = cur.next;
cur.next = next;
/*这里要先判断curcopy.next存不存在*/
if (next != null) {
curcopy.next = next.next;
} else {
curcopy.next = null;
}
cur = next;//这里千万要注意,它要往前移动
}
return res;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值