【剑指Offer】T35 复杂链表的复制

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的 head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

思路:复制,设置指针,分裂。示意图见 P187

分裂的那一步出错了,没有Clone = Clone->next;

/*
struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x), next(NULL), random(NULL) {
    }
};
*/
class Solution {
public:
    // 克隆
    void CloneNodes(RandomListNode* pHead){
        RandomListNode* p = pHead;
        while(p){
            // 没有判断p->next是因为没有对p->next取值,所以可以操作
            RandomListNode* clone = new RandomListNode(0);
            clone->label = p->label; 
            clone->next = p->next; 
            clone->random = nullptr;
            p->next = clone;
            p = clone->next;
        }
    }
    
    // 设置Random指针
    void SetRandom(RandomListNode* pHead){
        RandomListNode* p = pHead;
        while(p){
            if(p->random != nullptr)
                p->next->random = p->random->next;
//            else
//                p->next->random = nullptr;
            // 上两行没必要,因为本来就是指向空
            p = p->next->next;
        }
    }
    // 分裂
    RandomListNode* Split(RandomListNode* pHead){
        RandomListNode* p = pHead;
        // 设置头结点的思想,让游标节点去执行连接工作,最后返回头结点
        RandomListNode* clone = nullptr;
        RandomListNode* cloneHead = nullptr;
        
        
        if(p){
            clone = pHead->next;
            cloneHead = clone;
            p->next = clone->next;
            p = p->next;
        }
        
        while(p){
            clone->next = p->next;
            clone = clone->next;
            p->next = clone->next;
            p = p->next;
        }
        return cloneHead;
    }
    
    RandomListNode* Clone(RandomListNode* pHead){
        CloneNodes(pHead);
        SetRandom(pHead);
        return Split(pHead);
    }
};

分裂操作中,设置头结点思想用过很多次。开始设置头结点和游标节点指向“头结点地址”,让游标节点往后走执行连接操作,操作完成后,返回的头结点即整个链表或树。

本文链接:https://ariser.cn/index.php/archives/385/
本站文章采用 知识共享署名4.0 国际许可协议进行许可,请在转载时注明出处及本声明!