LeetCode 138. Copy List with Random Pointer

 A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.


Listed two methods. One is using HashMap, one is copy without extra memory space.

Pointer operation needs special attention....


#include <vector>
#include <iostream>
#include <unordered_map>
using namespace std;

struct RandomListNode {
    int label;
    RandomListNode* next, *random;
    RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
};


RandomListNode* setUpList() {
    RandomListNode* head = NULL;
    int number_1 = 1;
    RandomListNode* tmp = new RandomListNode(number_1);
    tmp->next = head;
    head = tmp;

    int number_2 = 2;
    RandomListNode* tmp_second = new RandomListNode(number_2);
    tmp_second->next = head;
    head = tmp_second;

    return head;
}

void setUpRandom(RandomListNode* head) {
    RandomListNode* tmp = head;
    while(tmp) {
        RandomListNode* next = tmp->next;
        tmp->random = next;
        tmp = tmp->next;
    }
}

void printValue(RandomListNode* head) {
    RandomListNode* tmp = head;
    while(tmp) {
        cout << "the node is: " << tmp->label;
        if(tmp->random) {
            cout << " randome value is: " << tmp->random->label;
            cout << endl;
        }
        cout << endl;
        tmp = tmp->next;
    }
<pre name="code" class="cpp">}

// Make deep copy with extra O(n) memory.
RandomListNode* copyRandomList(RandomListNode* head) {
    if(!head) return NULL;
    RandomListNode* dummy = new RandomListNode(-1);    // make a dummy node as the duplicate head.
    RandomListNode* curr = dummy;
    unordered_map<RandomListNode*, RandomListNode*> oldToNew;
    RandomListNode* tmp = head;
    while(tmp) {
        RandomListNode* newNode = new RandomListNode(tmp->label);
        oldToNew[tmp] = newNode;
        curr->next = newNode;
        curr = curr->next;
        tmp = tmp->next;
    }
    tmp = head;
    while(tmp) {
        if(tmp->random) {
            oldToNew[tmp]->random = oldToNew[tmp->random];
        }
        tmp = tmp->next;
    }
    return dummy->next;
}

//      NULL 
//       |   
//    2->2'->1->1'->NULL
//    |      |  
//    ------>  
void copyNext(RandomListNode* head) {
    RandomListNode* tmp = head;
    while(tmp) {
        RandomListNode* next = tmp->next;
        RandomListNode* newNode = new RandomListNode(tmp->label);
        newNode->random = NULL;
        tmp->next = newNode;
        newNode->next = next;
        tmp = next;
    }
}
//      ------>
//      |      |
//   2->2'->1->1'->NULL

//   |      |
//   ------>
void copyRandom(RandomListNode* head) {
    RandomListNode* tmp = head;
    while(tmp) {
        if(tmp->random) {
            tmp->next->random = tmp->random->next;
        }
        tmp = tmp->next->next;
    }
}

//    2->1->NULL
//    |  |
//    -->
//
//    2'->1'->NULL
//    |   |
//    --->
RandomListNode* splitListNodes(RandomListNode* head) {
    RandomListNode* newHead = head->next;
    while(head) {
        RandomListNode* tmp = head->next;
        head->next = tmp->next;
        head = head->next;
        if(tmp->next) {
            tmp->next = tmp->next->next;
        }
    }
    return newHead;
}

// make deep copy without using extra memory.
RandomListNode* copyRandomListII(RandomListNode* head) {
    copyNext(head);
    copyRandom(head);
    return splitListNodes(head);
}


//                            NULL
//                             |
// The listNode is setUp as 2->1->NULL.
//                          |  |
//                           ->

//                           ->
int main(void) {
    RandomListNode* head = setUpList();
    setUpRandom(head);
    printValue(head);
    cout << endl;
    cout << "make a copy" << endl;
    cout << endl;
    RandomListNode* dup = copyRandomListII(head);
    printValue(dup);
}


你可能感兴趣的:(LeetCode 138. Copy List with Random Pointer)