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;
    }
};

 

posted @ 2014-10-13 13:25  smileheart  阅读(166)  评论(0编辑  收藏  举报