leetcode一道比较难的链表题

leetcode一道比较难的链表题_第1张图片
今天还是继续来分享我们的链表题,这个题目有点难,主要是思路比较难想,但是如果沥青思路写起来就比较简单了(我乱讲的)

随机链表的复制

leetcode一道比较难的链表题_第2张图片

这个是题目的描述,大家也可以在链接里看,那我把这道题目分成三个解题步骤,第一个步骤是我们拷贝一个一摸一样的结点在没个节点后面,但是一模一样的节点我们要把它的值拷贝过来很简单,但是如是是它的random呢,我们只知道图中的节点指向哪里,但是我们不知道它的random到底该怎么解决,那我们得先malloc一个节点,然后插入到上面节点的每一个后面,并把他们继续链接起来,然后进行值拷贝,就是拷贝val这个值,步骤一我们只要完成val的赋值在加上在没一个节点的后面进行链接就行了,我们这里的思路是写一个循环用cur表示当前的位置,copy就是我们需要在cur节点后面进行链接的节点,下面给大家一个图,让大家更好的理解我们的意思和代码。

leetcode一道比较难的链表题_第3张图片
那我们就需要在每个节点后面链接,我们这里相当于单链表的随即插入要进行的步骤,首先我们得要一个next的指针来保存后面的节点,这样才能进行链接要不然cur进行下一个步骤的时候就会存在链接不上。步骤一的代码

struct Node* cur = head;
   
    while(cur)
    {
        struct Node* next = cur->next;
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;
        cur->next = copy;
        copy->next = next;
        cur = next;
    }

这样就能保证我们上面的这个图也是可以成立的,其实这道题的暴力求解也可以解决,但是会存在问题,时间复杂度是O(N的平方),我们的步骤二就是该解决我们random,大家有没有想过我们步骤一的作用就那么简单,其实不是的,因为我们的下一步就是需要怎么样把random放到我们malloc的节点,我们的的cur节点的random是不是可以准确找到,那我们copy的random是不是就是该cur节点的random的next这个节点就是我们当前copy这个节点,步骤一不仅仅把val进行值拷贝,还起到我们链接的作用,代码就是

 cur = head;
    struct Node* copy = cur->next;
    while(cur)
    {
        if(cur->random == NULL)
        {
            copy->random = NULL;

        }
        else
        {
            copy->random = cur->random->next;
        }
        cur = cur->next->next;
        if(cur)
            copy = cur->next;
    }

下一步取出这些节点,在进行链接就行,我们可以用单链表的尾插思路进行实现,我因为之前文章写过尾插的思路,这里就直接给出代码。


    cur = head;
    
    struct Node* newhead = NULL;
    struct Node* tail = NULL;
    while(cur)
    {
        struct Node* copy = cur->next;
         struct Node* next = copy->next;
        if(newhead == NULL)
        {
            newhead = copy;
            tail = copy;
        }
        else
        {
            tail->next = copy;
            tail = tail->next;
        }
        cur->next = next;
        cur = next;

    }
    tail->next = NULL;

那我们运行编译之后还有就是如果我们的链表是空的情况就直接返回空指针就可以了,下面就是我们这道题的完整代码。

struct Node* copyRandomList(struct Node* head) {
	struct Node* cur = head;
    if(head == NULL)
        return NULL;
    while(cur)
    {
        struct Node* next = cur->next;
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;
        cur->next = copy;
        copy->next = next;
        cur = next;
    }
    cur = head;
    struct Node* copy = cur->next;
    while(cur)
    {
        if(cur->random == NULL)
        {
            copy->random = NULL;

        }
        else
        {
            copy->random = cur->random->next;
        }
        cur = cur->next->next;
        if(cur)
            copy = cur->next;
    }

    cur = head;
    
    struct Node* newhead = NULL;
    struct Node* tail = NULL;
    while(cur)
    {
        struct Node* copy = cur->next;
         struct Node* next = copy->next;
        if(newhead == NULL)
        {
            newhead = copy;
            tail = copy;
        }
        else
        {
            tail->next = copy;
            tail = tail->next;
        }
        cur->next = next;
        cur = next;

    }
    tail->next = NULL;
   
    return newhead;
       

}

那今天的分享就到这里,我们下次再见。
leetcode一道比较难的链表题_第4张图片

你可能感兴趣的:(leetcode,链表,算法)