首页 > 其他分享 >[leetcode]复制带随机指针的链表

[leetcode]复制带随机指针的链表

时间:2023-04-27 11:39:15浏览次数:47  
标签:Node 结点 cur struct next 链表 copy leetcode 指针

力扣链接


[leetcode]复制带随机指针的链表_头结点

思路一:

遍历链表,将链表结点复制下来,控制随机指针,去找对应的第几个(相对位置)进行链接.

[leetcode]复制带随机指针的链表_头结点_02

思路二:

以时间换空间,创建两个指针数组,分别存放两个链表中结点的地址,直接可以在指针数组中找到结点

该方法比上面的方法更优,但是时间复杂度依旧很高,但是还是达不到O(N)


思路三:

[leetcode]复制带随机指针的链表_链表_03

1.拷贝结点链接在原结点后面

将每个原结点复制,

将复制后得到的结点分别链接到原结点的后面

[leetcode]复制带随机指针的链表_头结点_04

//1.插入拷贝结点在原结点的后面
    struct Node* cur = head;
    while(cur)
    {
        //插入
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;
        struct Node* next = cur->next;

        //链接
        cur->next = copy;
        copy->next = next;

        cur = next;
    }

2.拷贝结点的random是原结点random的next

[leetcode]复制带随机指针的链表_链表_05

例如:13的random是7,7的random->next是拷贝的7

拷贝的13的random刚好是拷贝的7

//处理拷贝的结点的random
    cur = head;
    while(cur)
    {
        struct Node* copy = cur->next;
        if(cur->random == NULL)
        {
            copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;


        }


        cur = cur->next->next;
    }

3.拷贝结点解下来,连接成一个新链表,原链表恢复

将拷贝的链表尾插成新链表


//拷贝结点解下来,连接成新链表,并且恢复原链表
    //这里选择不带哨兵位头结点的尾插
    struct Node* copyhead = NULL,*copyTail = NULL;//定义了新链表头copyhead和尾copyTail
    cur = head;
    while(cur)
    {
        struct Node* copy = cur->next;
        struct Node* next = copy->next;


        //copy尾插
        if(copyhead == NULL)
        {
            copyhead = copyTail = copy;
        }
        else
        {
            copyTail->next = copy;
            copyTail = copyTail->next;


        }


        //恢复原链表
        cur->next = next;


        cur = next;


    }
    return copyhead;
}

完整代码:

/**
 * Definition for a Node.
 * struct Node {
 *     int val;
 *     struct Node *next;
 *     struct Node *random;
 * };
 */


struct Node* copyRandomList(struct Node* head) 
{
    //1.插入拷贝结点在原结点的后面
    struct Node* cur = head;
    while(cur)
    {
        //插入
        struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
        copy->val = cur->val;
        struct Node* next = cur->next;


        //链接
        cur->next = copy;
        copy->next = next;


        cur = next;
    }
    



    //处理拷贝的结点的random
    cur = head;
    while(cur)
    {
        struct Node* copy = cur->next;
        if(cur->random == NULL)
        {
            copy->random = NULL;
        }
        else
        {
            copy->random = cur->random->next;


        }


        cur = cur->next->next;
    }


    //拷贝结点解下来,连接成新链表,并且恢复原链表
    //这里选择不带哨兵位头结点的尾插
    struct Node* copyhead = NULL,*copyTail = NULL;
    cur = head;
    while(cur)
    {
        struct Node* copy = cur->next;
        struct Node* next = copy->next;


        //copy尾插
        if(copyhead == NULL)
        {
            copyhead = copyTail = copy;
        }
        else
        {
            copyTail->next = copy;
            copyTail = copyTail->next;


        }


        //恢复原链表
        cur->next = next;


        cur = next;


    }
    return copyhead;
}




标签:Node,结点,cur,struct,next,链表,copy,leetcode,指针
From: https://blog.51cto.com/u_15992140/6230085

相关文章

  • const关键字_常量指针与指针常量
    变量被const修饰,能且仅能被赋值一次。指针被const修饰,只在初始化时指向一个对象,且不能更改指向常量:不能被二次赋值constinta;intconsta;常量指针和指针常量constint*p;//*p不能被二次赋值int*constp;//p不能被二次指向constint*constp;//*p不能第二次赋值,指针p不......
  • leetcode-350-两个数组的交集 II 题解
    题目给定两个数组,编写一个函数来计算它们的交集。示例1:输入:nums1=[1,2,2,1],nums2=[2,2]输出:[2,2]示例2:输入:nums1=[4,9,5],nums2=[9,4,9,8,4]输出:[4,9]说明:输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。我们可以不考虑输出结果......
  • 合并两个有序链表--Python实现
    将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。#Definitionforsingly-linkedlist.#classListNode:#def__init__(self,x):#self.val=x#self.next=NoneclassSolution:defmergeT......
  • C语言--指针
    【指针的类型】short* int* long* char* double* …指针的类型决定了指针向前或向后一步的步长(距离),其步长对应类型的大小。【指针的解引用】指针类型决定了对指针解引用的时候有多大的权限(能操作几个字节)。比如char的指针解引用就只能访问1个字节,而int的指针解引用就能访......
  • 1351. 统计有序矩阵中的负数(leetcode)
    https://leetcode.cn/problems/count-negative-numbers-in-a-sorted-matrix/1351.统计有序矩阵中的负数1.二分法:把每一行进行一遍二分,找到正数与负数的边界,且此时grid[i][mid]也为负数,即边界下标的对应值是负数的左半边界那么一行中的个数即为size()-lclassSolution{pu......
  • C语言指针的感悟
    写这篇文章要感谢(微信公众号 C语言与CPP编程里C++指针详解)此处我写的就是看过那篇文章后的一点启发(例如:如何取出一个4个字节int类型数的第三个字节存储的内容之类的问题)#include<iostream>usingnamespacestd;intmain(){intm=65536;char*p=(char......
  • #yyds干货盘点# LeetCode程序员面试金典:解数独
    题目:编写一个程序,通过填充空格来解决数独问题。数独的解法需遵循如下规则:数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)数独部分空格内已填入了数字,空白格用 '.' 表示。 示例1......
  • #yyds干货盘点# LeetCode面试题:合并两个有序数组
    1.简述:给你两个按非递减顺序排列的整数数组 nums1和nums2,另有两个整数m和n,分别表示nums1和nums2中的元素数目。请你合并nums2到nums1中,使合并后的数组同样按非递减顺序排列。注意:最终,合并后数组不应由函数返回,而是存储在数组nums1中。为了应对这种情况,nums1......
  • 链表相交
     题目:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 需要注意的点:1、定义的两个指针在遍历完链表的长度后,要重新指向头结点2、让长、短链表的尾端对齐3、相交意味着指针相同 classSolution{p......
  • 删除链表的倒数第N个节点
    题目:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。输入:head=[1,2,3,4,5],n=2输出:[1,2,3,5]本题需要使用双指针,需要注意的点:1、双指针都指向头结点2、快指针提前移动n+1个点3、结束条件:快指针指向空指针4、慢指针指向要删除结点的前一个结点5、删除结点时......