LeetCode第138题---复制带随机指针的链表

复制带随机指针的链表

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
提示:这个题算是一个复杂链表,因为它里面还有一个random的随机指针,题目要求复制这个复杂链表。

解题思路:①拷贝结点链接在原结点的后面,然后将他们连接起来,②处理拷贝结点的random那么你复制的结点random就是你原结点random的后面一个,然后拆解出你复制的链表。

①拷贝结点,链接到原节点的后面

在这里插入图片描述

    Node* cur = head;
    //当cur为空的时候,就不需要再继续拷贝结点了,作为结束的判断条件
    while(cur)
    {
    
    
        //一个一个创造结点,然后在链接
        Node* copy = (Node*)malloc(sizeof(Node));
        //一定不要忘记对于malloc出来的结点对其进行初始化,不然里面就是随机值,或许到后面就会出现不必要的错误,麻烦
        copy->next = NULL;
        copy->random = NULL;
        copy->val = cur->val;

        //一定要先进行这一步,因为你如果直接和新结点相连接,那么新节点去找原结点的下一个的时候就找不到了
        Node* next = cur->next;
        cur->next = copy;
        copy->next = next;
        //让这三个cur copy next 遍历起来
        cur = next;
    }

2.处理拷贝结点的random
每个拷贝结点都链接在原结点的后面,那么是不是可以认为拷贝结点的random也在原结点random的后面一个。(这里就很好的避开了一种情况----当你的结点中的val出现了两个相同的数值时候,我的random不知道该去找哪一个,因为对于random来说只能通过值来寻找,他并不知道他随机指向的地址,数值相同就是它所能找到的判断标准)

    //处理拷贝结点的random
    //因为你上面的操作,使你的cur都走到空了,现在我需要重头开始思考问题
    cur = head;
    while(cur)
    {
    
    
        Node* copy = cur->next;
        if(cur->random)
        //一定要小心谨慎,你的random是有可能为NULL的
            copy->random = cur->random->next;
        else
            cur->random = NULL;
        //然后让其迭代起来
        cur = cur->next->next;
    }

3.拆解出来拷贝的链表
在这里插入图片描述

    //③拆解出来拷贝的链表
    cur = head;
    //题目要求最终返回拷贝链表的头
    //如果链表是NULL的,那么你这里的head->next就会崩溃,这也是一种测试用例,需要考虑进去
    Node* copyHead = head->next;
    while(cur)
    {
    
    
        Node* copy = cur->next;
        Node* next = copy->next;
        
        cur->next = next;
        if(next)
            copy->next = next->next;
        else
            copy->next = NULL;
        //迭代起来
        cur = next;
    }

完整代码

/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     struct Node *next;
 *     struct Node *random;
 * };
 */
//复杂链表里面还有一个random指针
typedef struct Node Node;
struct Node* copyRandomList(struct Node* head) {
    
    
    if(head == NULL)
        return NULL;
	//1.拷贝结点链接在原结点的后面
    Node* cur = head;
    while(cur)
    {
    
    
        //一个一个创造结点,然后在链接
        Node* copy = (Node*)malloc(sizeof(Node));
        //一定不要忘记对于malloc出来的结点对其进行初始化,不然里面就是随机值,或许到后面就会出现不必要的错误,麻烦
        copy->next = NULL;
        copy->random = NULL;
        copy->val = cur->val;

        //一定要先进行这一步,因为你如果直接和新结点相连接,那么新节点去找原结点的下一个的时候就找不到了
        Node* next = cur->next;
        cur->next = copy;
        copy->next = next;
        //让这三个cur copy next 遍历起来
        cur = next;
    }
    //处理拷贝结点的random
    //因为你上面的操作,使你的cur都走到空了,现在我需要重头开始思考问题
    cur = head;
    while(cur)
    {
    
    
        Node* copy = cur->next;
        if(cur->random)
        //一定要小心谨慎,你的random是有可能为NULL的
            copy->random = cur->random->next;
        else
            cur->random = NULL;
        //然后让其迭代起来
        cur = cur->next->next;
    }
    //③拆解出来拷贝的链表
    cur = head;
    //题目要求最终返回拷贝链表的头,一开始我就把它保留下来
    Node* copyHead = head->next;
    while(cur)
    {
    
    
        Node* copy = cur->next;
        Node* next = copy->next;
        
        cur->next = next;
        if(next)
            copy->next = next->next;
        else
            copy->next = NULL;
        //迭代起来
        cur = next;
    }
    return copyHead;
}

但是这道题的解题思路是有些不好的,因为算是一种侵入式的解题,你在解题的过程中自己修改了原链表,但是在多线程(并发操作时)这个链表还有别人在使用的时候呢?你修改了,那别人在访问他的时候就会出现错误!

猜你喜欢

转载自blog.csdn.net/MEANSWER/article/details/111968060
今日推荐