剑指offer——三步走法原地修改解复制复杂链表

用哈希表不是最佳答案,最好的方法是原地修改法:

  1. 复制一个新的节点在原有节点之后,如 1 -> 2 -> 3 -> null 复制完就是 1 -> 1 -> 2 -> 2 -> 3 - > 3 -> null
  2. 从头开始遍历链表,通过 cur.next.random = cur.random.next 可以将复制节点的随机指针串起来,当然需要判断 cur.random 是否存在
  3. 将复制完的链表一分为二

图解步骤:

原链表:

首先复制

再处理连接random节点

最后一分为二

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/
class Solution {
public:
    Node* copyRandomList(Node* head) {
        CloneNodes(head);
        Connectrandom(head);
        return Reconnect(head);
    }
    void CloneNodes(Node* head){
        //创建新节点并将新节点连接到原节点后面
        Node* node = head;
        while(node!=nullptr){
            Node* clone = new Node(-1);
    //此处不能简单clone = node进行复制,因为两者指向的下一个节点是不同的!
            clone->val = node->val;
            clone->next = node->next;
            clone->random = nullptr;//记得先将random置空,下一步处理
            //将克隆结点和原节点都向前移动
            node->next = clone;
            node = clone->next;
        }
    }
    void Connectrandom(Node* head){
        //将原节点的random节点对应在前面复制节点的相应位置进行复制
        Node* node = head;
        while(node!=nullptr){
            Node* clone = node->next;
            if(node->random!=nullptr){
                clone->random = node->random->next;
            }
            node = clone->next;
        }
    }
    Node* Reconnect(Node* head){
        //将刚才复制的链表拆成两个
        Node* node = head;
        Node* clonehead = nullptr;
        Node* clone = nullptr;

        if(node!=nullptr){//获得克隆的头结点
            clonehead = clone = node->next;
            node->next = clone->next;
            node = node->next;
        }

        while(node!=nullptr){
            clone->next = node->next;
            clone = clone->next;//克隆节点前移
            node->next = clone->next;
            node = node->next;//结点前移
        }
        return clonehead;
    }
    
};
发布了377 篇原创文章 · 获赞 344 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_41895747/article/details/104856094