這是一道算法題。想寫篇blog記錄一下這道題的解法。
題目是這樣的:
輸入一個複雜鏈表(每一個節點中有節點值,以及兩個指針,一個指向下一個節點,另外一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,不然判題程序會直接返回空)
這道題什麼意思呢?它的意思就是說,我有一個節點類型,這個節點類型有三個成員,其中一個成員存放值,另外另個成員分別是兩個指針,一個是next指針,指向下一個節點;還有一個是random指針,指向鏈表中的任意一個節點。這個節點類型跟咱們以前見到的節點類型有點不太同樣,不同之處就是多了一個指向任意節點的random指針。別的就沒什麼不一樣了。以下圖所示:
(這圖徹底是本身用微軟自帶的畫圖工具畫的,不太好看,可是不影響理解,哈哈~)
理解了題意,如今來寫解法。
這道題有兩種解法,第一種是使用額外空間的解法,比較簡單;另外一種是不使用額外空間的解法,寫法比較奇妙,可是比較難寫;
如今先講第一種使用額外空間的寫法。用額外空間呢,就是使用一個Map。
首先遍歷一遍鏈表,將鏈表中全部節點都在Map中存儲下來。哦,對了,map就是<key,value>類型的一種結構,若是不瞭解的同窗,請自行百度,網上不少關於map的介紹。
代碼以下:ios
cur = pHead; while(cur != NULL){ map.insert(pair<RanomListNode*, RandomListNode*>(cur, new RandomListNode(cur->value)); cur = cur->next; }
這只是一個代碼片斷,裏面出現的東西,下面會有完整介紹。
此時,我在map中已經存有和現有鏈表同樣多的節點了,而且節點值也是同樣的。只是,咱們尚未設置map中節點的next指針和random指針,換言之,這時map中的全部節點是斷開的。
以下圖:
很明顯,咱們知道接下來要作什麼。就是將這些節點按照題目給出的鏈表模樣串起來。
其次,將拷貝節點按照原鏈表鏈接好它們的next指針和random指針。
那麼怎麼串呢?咱們看一下上面兩張圖,1的next指針連的是2,所以咱們的拷貝節點1'就得連2'。也就是說,咱們須要經過map去找到節點1的拷貝節點1‘,而後經過map去找到1的下一個節點的拷貝節點2'。這不是很好理解,經過代碼展現什麼意思:算法
myMap[cur]->next = myMap[cur->next];
根據代碼來看,咱們經過myMap[cur]找到cur的拷貝節點,這個拷貝節點的next指針指向了cur節點下一個節點的拷貝節點。這樣,就把兩個拷貝節點鏈接起來了。
random指針同理設置。
代碼以下:微信
myMap[cur]->random = myMap[cur->random];
最後一步,返回拷貝鏈表的頭節點。由於,此時拷貝節點都串起來了,造成了完整的鏈表,只要返回鏈表頭部,就能獲得整個拷貝鏈表了。到此,全部步驟就已經結束了。
下面是完整代碼:dom
#include <iostream> #include <map> using namespace std; struct RandomListNode{ int value; Node* next; Node* random; Node(int value) : value(value), next(NULL), random(NULL){ } }; class CopyListWithRandom { public: RandomListNode* Clone(RandomListNode* pHead) { if(pHead == NULL) return NULL; map<RandomListNode*, RandomListNode*> myMap; RandomListNode* cur = pHead; while(cur != NULL){ myMap.insert(pair<RandomListNode*, RandomListNode*>(cur, new RandomListNode(cur->value))); cur = cur->next; } cur = pHead; while(cur != NULL){ myMap[cur]->next = myMap[cur->next]; myMap[cur]->random = myMap[cur->random]; cur = cur->next; } return myMap[pHead]; } };
運行結果:
測試代碼就本身寫一下吧,比較簡單。這種寫法的關鍵是要掌握map的使用,別的也沒有什麼了。ide
至於不用額外空間的寫法,那就更逆天了,下次再寫吧,哈哈~工具
感謝各位大佬的閱讀。歡迎評論,歡迎點贊~測試
================================================================================================================
若是能夠的話,打個賞也行啊,哈哈~
一毛兩毛也表示萬分感謝,哈哈~spa
下面是個人支付寶及微信二維碼