leetcode刷题05--复杂的链表的深度拷贝--T138

题目:


深度拷贝:
构造一个完全新的链表,即使将原链表毁坏,新链表也可以独立使用

自己的思路:
无…

好吧看一下ppt的思路:
ppt中的解法,利用到了stl中的map:
知识补充:

std::map


map是一种映射的数据格式
在这里可以将链表节点地址作为map序号,其映射值为该地址对应的链表节点序列

该工具足矣解决该问题的难点:
如何在新链表中保留旧链表random指针所指向的相对位置

std::vector

vector(向量):是一种顺序容器,事实上和数组差不多,但它比数组更优越。一般来说数组不能动态拓展,因此在程序运行的时候不是浪费内存,就是造成越界。而vector正好弥补了这个缺陷,它的特征是相当于可分配拓展的数组,它的随机访问快,在中间插入和删除慢,但在末端插入和删除快。

思路:

用一个map,存放原链表的序号和地址的映射关系,和一个vector,存放存放新链表的序号和地址的映射关系
之所以不用两个map,是由于新链表要通过序号找地址;当然,用一个结构和前者相反的map也可以,不过有些不好用
所以可以得到每个原链表节点的random指针所指向的节点的序号,并应用在新链表中:
head_new->random = vector[map[head.random]]


代码:

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;

    Node() {}

    Node(int _val, Node* _next, Node* _random) {
        val = _val;
        next = _next;
        random = _random;
    }
};
*/
class Solution {
public:
    Node* copyRandomList(Node* head) {
        //创建一个map和一个vector
        std::map<Node*, int> node_map;
        //vector同时也用来存放新的链表
        std::vector<Node*> node_vec;
        //指向起始节点
        Node* ptr = head;
        //记录序号
        int i = 0;
        //遍历原链表,将结构存入map中
        while(ptr){
            //同时创建新链表节点
            node_vec.push_back(new Node(ptr->val,NULL,NULL)); 
            //确定映射关系
            node_map[ptr] = i;
            //指向下一个
            ptr = ptr->next;
            i++;
        }
        //将尾节点置0是让其不需要特殊化处理尾节点  0为空?
        node_vec.push_back(0);
        ptr = head;
        i = 0;
        //将原链表中random的关系迁移到新链表中
        while(ptr){
            //链表关系
            node_vec[i]->next = node_vec[i+1];
            //random不为空才记录
            if(ptr->random){
                //random关系
                //id = node_map[ptr->random]
                 node_vec[i]->random = node_vec[node_map[ptr->random]];
            }
            ptr = ptr->next;
            i++;
            
        }
        return node_vec[0];
        
    }
};

总结:
今天写的不好,效率不够高,花了1个多小时做这个,而且主要的时间被浪费到了琐事之上,引以为戒!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值