Copy List With Random Pointer (LeetCode)
Question:
https://oj.leetcode.com/problems/copy-list-with-random-pointer/
解答:
最初的想法是把指针转换成int,然后把Random表也变成vector<int>, vector里的值表示第i个指针的random指向哪里。
/** * Definition for singly-linked list with a random pointer. * struct RandomListNode { * int label; * RandomListNode *next, *random; * RandomListNode(int x) : label(x), next(NULL), random(NULL) {} * }; */ class Solution { public: RandomListNode *copyRandomList(RandomListNode *head) { vector<RandomListNode*> nodeArray; std::map <RandomListNode*, int> nodeIndexMap; vector<int> nodeRandomArray; RandomListNode* curr = head; while (1) { nodeArray.push_back(curr); nodeIndexMap[curr] = nodeArray.size()-1; if (curr == NULL) break; curr = curr->next; } curr = head; while (curr) { nodeRandomArray.push_back(nodeIndexMap[curr->random]); curr = curr->next; } vector<RandomListNode*> newArray(nodeArray.size(), NULL); for (int i = nodeArray.size()-2; i >= 0; i--) { newArray[i] = new RandomListNode(nodeArray[i]->label); newArray[i]->next = newArray[i+1]; } // set random pointer for (int i = 0; i < nodeRandomArray.size(); i++) newArray[i]->random = newArray[nodeRandomArray[i]]; return newArray[0]; } };
其实不必要这么麻烦,直接把新老节点进行map,就简单了。
class Solution { public: RandomListNode *copyRandomList(RandomListNode *head) { map<RandomListNode*, RandomListNode*> newNodeMap; RandomListNode* curr = head; RandomListNode* prevNewNode = NULL; RandomListNode* newHead = NULL; while (curr) { RandomListNode* newNode = new RandomListNode(curr->label); newNodeMap[curr] = newNode; if (prevNewNode) { prevNewNode->next = newNode; } else { newHead = newNode; } prevNewNode = newNode; curr = curr->next; } // set random pointer curr = head; while (curr) { if (curr->random) { newNodeMap[curr]->random = newNodeMap[curr->random]; } curr= curr->next; } return newHead; } };
网上看到一个解法更巧妙,没有用到extra space. 就是把新节点插入到旧节点后面,然后设置新节点的random(就是旧节点random点的后面一个节点). 最后再过新节点从原来的Linked List中拿出来返回。
class Solution { public: RandomListNode *copyRandomList(RandomListNode *head) { if (!head) return NULL; RandomListNode* curr = head; while (curr) { RandomListNode* newNode = new RandomListNode(curr->label); newNode->next = curr->next; curr->next = newNode; curr = newNode->next; } curr = head; while (curr) { if (curr->random) { curr->next->random = curr->random->next; } curr = curr->next->next; } RandomListNode* newHead = NULL; RandomListNode* newPrev = NULL; curr = head; while (curr) { if (newPrev) { newPrev->next = curr->next; } else { newHead = curr->next; } newPrev = curr->next; curr->next = curr->next->next; curr = curr->next; } return newHead; } };