美文网首页
剑指offer 36- 复杂链表的复刻

剑指offer 36- 复杂链表的复刻

作者: 顾子豪 | 来源:发表于2021-05-23 12:25 被阅读0次

请实现一个函数可以复制一个复杂链表。

在复杂链表中,每个结点除了有一个指针指向下一个结点外,还有一个额外的指针指向链表中的任意结点或者null。

注意:

  • 函数结束后原链表要与输入时保持一致。

分析:
算法一:


1.把原链表的每个结点后面都接一个同样的结点
2.修改结点的random指针:p->next->random = p->random->next
3.定义一个虚拟头结点dummy,将复制的出来的结点串起来
总时间复杂度:O(N)

  • 这种做法修改了原始链表
/**
 * Definition for singly-linked list with a random pointer.
 * struct ListNode {
 *     int val;
 *     ListNode *next, *random;
 *     ListNode(int x) : val(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *copyRandomList(ListNode *head) {
        
        /*
        1.把原链表的每个结点后面都接一个同样的结点
        2.修改结点的random指针:p->next->random = p->random->next
        3.定义一个虚拟头结点dummy,将复制的出来的结点串起来
        总时间复杂度:O(N)
        */
        
        for (auto p = head; p;) {
            auto np = new ListNode(p->val);
            auto temp = p->next;
            p->next = np;
            np->next = temp;
            p = temp;
        }
        for (auto p = head; p; p = p->next->next) {
            if(p->random)
                p->next->random = p->random->next;
        }
        
        auto dummy = new ListNode(-1);
        auto cur = dummy;
        for(auto p = head; p; p=p->next) {
            cur->next = p->next;
            cur = cur->next;
            p = p->next;
        }
        
        return dummy->next;
    }
};

算法二:
借助哈希表
O(n)
使用hash存储 key = 源链表节点,value = 目标链表节点,遍历源链表,判断每个节点和random节点是否在hash表中,如果不存在则创建

/**
 * Definition for singly-linked list with a random pointer.
 * struct ListNode {
 *     int val;
 *     ListNode *next, *random;
 *     ListNode(int x) : val(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *copyRandomList(ListNode *head) {
        unordered_map<ListNode*, ListNode*> hash;
        hash[nullptr] = nullptr;
        auto dummy = new ListNode(-1);
        auto cur = dummy;
        for(;head;head = head->next, cur= cur->next) {
            if(!hash.count(head)) hash[head] = new ListNode(head->val);
            if(!hash.count(head->random)) hash[head->random] = new ListNode(head->random->val);
            cur->next = hash[head];
            cur->next->random = hash[head->random];
        }
        return dummy->next;
    }
};

相关文章

网友评论

      本文标题:剑指offer 36- 复杂链表的复刻

      本文链接:https://www.haomeiwen.com/subject/qgzljltx.html