LeetCode——Copy List with Random Pointer

本文介绍两种链表复制方法:一种使用额外空间映射原链表与新链表节点对应关系,时间复杂度O(n),空间复杂度O(n);另一种通过对链表结构的巧妙利用实现空间复杂度O(1)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载自https://blog.youkuaiyun.com/linhuanmars/article/details/22463599/

不能一次扫描就生成复制链表,因为随机指针指向的节点可能还没有创建

解法1 :对链表进行两次扫描,第一次顺接生成next值,并将原链表与新链表相应节点作为一对值存入一个map

第二次扫描,根据map得出各节点random指针的指向。

时间复杂度o(n),空间复杂度o(n)

/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
#include<cstdlib>
#include<iostream>
#include <map>
using namespace std;

class Solution {
public:
    	RandomListNode *copyRandomList(RandomListNode *head) {
		if (head == NULL)
			return head;
    		map<RandomListNode*, RandomListNode*> mymap;
		RandomListNode* newHead = new RandomListNode(head->label);
		mymap.insert(pair<RandomListNode*, RandomListNode*>(head, newHead));
		RandomListNode* pre = newHead;
		RandomListNode* node = head->next;
		while (node != NULL)
		{
			RandomListNode* newNode = new RandomListNode(node->label);
			mymap.insert(pair<RandomListNode*, RandomListNode*>(node, newNode));
			pre->next = newNode;
			pre = newNode;
			node = node->next;
		}
		node = head;
		//RandomListNode* copyNode = newHead;
		while (node != NULL)
		{
			mymap[node]->random = mymap[node->random];
			node = node->next;
		}
		return newHead;
	}
};


调错总结:

(1)开始用的小写null,显示undefined,加了头文件<cstdlib><iostream>名称空间std还是报错,换成大写NULL解决!

(2)判断为控是判断指针,而不是指针指向的对象,否则报错 == 运算符左右不匹配

(3)开始用HashMap,包含了头文件hash_map还是无法识别该类型,不知道怎么回事,换成map就可以了

STL中关于map, hash_map的方法get, put, insert还得复习一下。

法2:想避免使用额外空间,只能通过利用链表原来的数据结构来存储节点。基本思路是,对链表进行三次扫描,第一次扫描对每个节点进行复制,然后把复制出的新节点接在原节点的next,也就是让链表变成一个重复链表;第二次把旧节点的随机指针赋给新节点的随机指针,因为新节点都跟在旧节点的下一个,有node.next.random=node.random.next;最后一次扫描把链表拆成两个,第一个还原原链表,第二个就是要求的复制链表,把每隔两个节点分别相连。

时间复杂度o(n),空间复杂度o(1)(因为不需要额外空间)。

class Solution {
public:
	RandomListNode *copyRandomList(RandomListNode *head) {
        if(head == NULL)
            return head;
        RandomListNode *node = head, *nextNode = NULL, *pre = NULL;
        while(node != NULL)
        {
            nextNode = node->next;
            RandomListNode * newNode = new RandomListNode(node->label);
            node->next = newNode;
            newNode->next = nextNode;
            pre = node;
            node = nextNode;
        }
        RandomListNode *lastNode = new RandomListNode(pre->label);
        pre->next = lastNode;
        lastNode->next = NULL;
        
        // 第二次扫描,赋random指针值
        node = head;
        while(node!= NULL)
        {
            if(node->random!= NULL)
                node->next->random = node->random->next;
            else
                node->next->random = NULL;
            node = node->next->next;
        }
        
        // 第三次扫描,分类原链表和复制链表(这里写得有些冗余.....)
        node = head;
        RandomListNode *copyNode = node->next, *copyHead = node->next; 
        while(node->next->next != NULL)
        {
            nextNode = node->next->next;
            copyNode->next = nextNode->next;
            node->next = nextNode;
            node = nextNode;
            copyNode = node->next;
        }
        node->next = NULL;
        copyNode->next = NULL;
        return copyHead;
        
	}
};

调错总结:

member access within null pointer of type 'RandonListNode  struct '

原因:如果原链表某节点的随机指针指向的是NULL,则它不在复合链表中,没有下一个节点,复制链表中相应节点的随机指针也该为NULL。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值