[LeetCode] Copy List with Random Pointer

http://oj.leetcode.com/problems/copy-list-with-random-pointer/我用hash表ac的, 但是有更优雅的方法, 我是沙茶, 我想不出, 又看了题解, 题解的方法我总结如下:

每生成一个新结点, 就连到相应旧结点的next指针上, 这样形成了原链表和新链表每个结点依次先后相邻的一条链表,相当于一个合并的过程. 也许这步让人不明所以, 那么接下来的步骤就是关键, 把每个新结点的random指针指向该新结点前面那个旧节点的random指针的next, 这句话有点绕, 其实画个图更好理解. 懒的画图了, 使劲看会明白的. 最后一步就是把这个合并后的链表中的新链表分离出来,得到最终答案. 其实这个算法的原理就是建立旧链表结点和新链表结点的关系, 方便通过旧结点快速找到新结点. 我们最开始思考这道题的时候 要知道 这道题的瓶颈在于如何确定旧结点random指针所指向的旧结点对应着哪一个新结点, 如何建立旧节点和新结点的联系, 所以会自然而然的想到将新旧节点通过指针连起来, 而单链表只有一个指针, 不可能分出多路, 所以就只能把两个链表相邻串在一起形成一个链表.

下面代码是用hash实现的, 并不是我上面讲述的优雅算法的实现, 所以很丑.

class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
        if (head == NULL) {
            return NULL;
        }
        unordered_map<RandomListNode*, int> m;
        RandomListNode* n[20480] = {0};
        RandomListNode* newHead = new RandomListNode(head->label);
        m[head] = 0;
        n[0] = newHead;
        RandomListNode* pNode = head->next;
        RandomListNode* pNewNode = newHead;
        RandomListNode* pPreNewNode = newHead;
        int index = 1;
        while (pNode) {
            m[pNode] = index;
            pNewNode = new RandomListNode(pNode->label);
            n[index] = pNewNode;
            pPreNewNode->next = pNewNode;
            pPreNewNode = pNewNode;
            pNode = pNode->next;
            index++;
        }
        index = 0;
        pNewNode = newHead;
        pNode = head;
        while(pNewNode) {
            if (pNode->random == NULL) {
                pNewNode = pNewNode->next;
                pNode = pNode->next;
                continue;
            }
            int i = m[pNode->random];
            pNewNode->random = n[i];
            pNewNode = pNewNode->next;
            pNode = pNode->next;
        }
        return newHead;
    }
};

 

posted @ 2013-11-05 01:25  NextLife  阅读(221)  评论(0)    收藏  举报