复制含有随机指针节点的链表~哈希表的使用~(⌒▽⌒)
題目意思就是說(shuō)給你給head 的Node節(jié)點(diǎn)(這是一個(gè)比較特殊的鏈表),來(lái)拷貝出它地結(jié)構(gòu)出來(lái)。
方法一:借助HashMap的特性,定義一個(gè)HashMap<Node,Node> map對(duì)象,key和value都是value類(lèi)型 ,key來(lái)存舊的鏈表,value來(lái)存新的鏈表。最后利用老節(jié)點(diǎn)和新節(jié)點(diǎn)的對(duì)應(yīng)關(guān)系來(lái)實(shí)現(xiàn)一個(gè)拷貝新的鏈表。
對(duì)于理解哈希表的同學(xué)來(lái)說(shuō),應(yīng)該不難理解,code也比較容易:
/* 方法一:借助HashMap,定義一個(gè)HashMap<Node,Node> map對(duì)象,key和value都是value類(lèi)型 */
public static Node copyListWithRandom1(Node head) {
HashMap<Node, Node> map = new HashMap<Node, Node>();
Node cur = head;
/* 將單鏈表的所有節(jié)點(diǎn)和value對(duì)應(yīng)放進(jìn)去map對(duì)象中 */
while (cur != null) {
map.put(cur, new Node(cur.value));// 這里新建一個(gè)節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)放head的value
cur = cur.next;
}
/* 重新構(gòu)建鏈表的結(jié)構(gòu),注意,此時(shí)map對(duì)象為map<cur,cur'>,cur'為新建立的節(jié)點(diǎn) */
cur = head;
/*
* 為了讓大家更好的理解,我們假設(shè)舊節(jié)點(diǎn)和舊節(jié)點(diǎn)的next還有舊節(jié)點(diǎn)rand分別為cur,curJiu,curRand
* (不懂的同學(xué)可以先去了解一下hashMap特點(diǎn))所以有:cur.next= curJiu,cur.rand= curRand
* 因此,為了保持這種結(jié)構(gòu),就有了(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:空間復(fù)雜度為O(1),只需要幾個(gè)變量就可以實(shí)現(xiàn),(不過(guò)個(gè)人覺(jué)得還是方法1更方便)不多說(shuō)了,直接附上圖:
編程如下:
/*這個(gè)方法空間復(fù)雜度為O(1),并且不用用到哈希表,相對(duì)來(lái)說(shuō)容易了許多,不過(guò)思路比較巧妙,主要就是三步走*/
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
* 變?yōu)楝F(xiàn)在的1 1 2 2 3 3 4 4 5 5 6 6?
* ?6 - 6 - 5 - 3 - - - 4 -
* 說(shuō)到底就是添加了next指針,而rand指針不變*/
Node next = null;
Node cur = head; //每個(gè)新的操作之前都要對(duì)cur賦值
while (cur != null) {
next = cur.next; //先保存這個(gè)節(jié)點(diǎn),同時(shí)也為了下面的移動(dòng)方便
cur.next = new Node(cur.value);
cur.next.next = next;
cur = next;//這里千萬(wàn)要注意,它要往前移動(dòng)
}
/*set copy node rand
* 也就是根據(jù)rand來(lái)設(shè)置新的鏈表的rand指針
* 從之前的1 2 3 4 5 6
* ? ? ? 6 6 5 3 - 4
* 變?yōu)楝F(xiàn)在的1 1 2 2 3 3 4 4 5 5 6 6?
* ?6 6 6 6 5 5 3 3 - - 4 4
* 說(shuō)到底就是添加了rand指針*/
cur = head; //每個(gè)新的操作之前都要對(duì)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; //這里千萬(wàn)要注意,它要往前移動(dòng)
}
/*split,將新建的鏈表和舊鏈表分離
* 斷開(kāi)新鏈表和舊鏈表的連接*/
cur = head; //每個(gè)新的操作之前都要對(duì)cur賦值
Node res = head.next; ?//定義這個(gè)節(jié)點(diǎn)是為了方便返回
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;//這里千萬(wàn)要注意,它要往前移動(dòng)
}
return res;
}
總結(jié)
以上是生活随笔為你收集整理的复制含有随机指针节点的链表~哈希表的使用~(⌒▽⌒)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java反射————Method根据方法
- 下一篇: Shiro————核心设计思想