当前位置: 首页 > news >正文

[LeetCode]—Copy List with Random Pointer 深度复制带“任意指针”的链表

Copy List with Random Pointer

 

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.


题目解读:

      关键难点:如果只是复制链表,O(n)的复杂度,遍历一遍就完成了。但是,有一个指针random,由于是深度复制,则random要指向相应新节点的位置。那就是题目的考察点所在。

     解题:1、先复制链表,然后比对“老链表”逐个对应寻找每个新节点的random指针的指向。时间复杂度为O(N^2)。这显然时间上是不满足题意的。

                 2、那么考虑,如何才能确定新random的指向呢?如果我们能够通过“老节点”找到对应“新节点”的位置,那么找random的问题就解决了。如图:




我们怎么才能从A找到A‘呢? 只能利用节点唯一可用的next指针,将A’连接在A的后面如果上图所示,那么这个关系就确定下来了。找random的问题就解决了。


具体方法:先依次复制所有链表节点,将“新节点”连接在“老节点”后面。并将“新节点”的random设为“老节点”的random值。第二次扫描链表,修正所有“新节点”的random值。

第三次扫描链表,区分开“老链表”和“新链表”形成两个链。时间复杂度为O(N)


注意:1、random是任意指向,有可能是指向NULL的。

           2、根据代码通过测试来看,由于是复制,似乎必须不能破坏原始的链表。所以最后需要形成完整的“新链表”和“老链表”。


/**
 * 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) {}
 * };
 */
 
class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        if(head==NULL)return NULL;

        RandomListNode *p,*q,*head_new;
        p=head;
        do{
            q=p->next;
            RandomListNode *node=new RandomListNode(p->label);
            p->next=node;
            node->next=q;
            node->random=p->random;
            p=q;
        }while(p!=NULL);

        p=head;
        do{
            q=p->next;
            q->random=(q->random!=NULL)?q->random->next:NULL;
            p=p->next->next;
        }while(p!=NULL);

        head_new=head->next;
        for(p=head,q=head_new;;){
            p->next=q->next;
            p=p->next;
            if(p==NULL)break;
            q->next=p->next;
            q=q->next;
        }

        return head_new;
    }
};



相关文章:

  • DB2使用Data Studio连接报ERRORCODE=-4499 SQLSTATE=08001
  • [LeetCode]—Implement strStr() 寻找子串匹配第一个位置 (KMP)
  • MFC图形函数(转载)
  • [LeetCode]—Add Binary 两个字符串二进制相加
  • 一个VC写的模拟时钟
  • [LeetCode]—Longest Palindromic Substring 最长回文子串
  • 串行通信技术SERDES
  • 从两种SQL表连接写法来了解过去
  • IT项目外包的4321法则
  • [LeeCode]—Wildcard Matching 通配符匹配问题
  • 快马探营:移动MM“热料”解密
  • [LeetCode]-Integer to Roman 阿拉伯数字转罗马数字
  • Ado.Net操作Excel文件数据常见问题及解决
  • [LeetCode]—Roman to Integer 罗马数字转阿拉伯数字
  • vim 全局批量替换
  • 【前端学习】-粗谈选择器
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • 07.Android之多媒体问题
  • es6
  • Git 使用集
  • HTML5新特性总结
  • Java小白进阶笔记(3)-初级面向对象
  • node.js
  • Solarized Scheme
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 解析带emoji和链接的聊天系统消息
  • 悄悄地说一个bug
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • #每天一道面试题# 什么是MySQL的回表查询
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (13)Hive调优——动态分区导致的小文件问题
  • (2.2w字)前端单元测试之Jest详解篇
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (3)选择元素——(17)练习(Exercises)
  • (HAL库版)freeRTOS移植STMF103
  • (附源码)php新闻发布平台 毕业设计 141646
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (学习日记)2024.02.29:UCOSIII第二节
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .Net 6.0 处理跨域的方式
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • :not(:first-child)和:not(:last-child)的用法
  • @configuration注解_2w字长文给你讲透了配置类为什么要添加 @Configuration注解
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • [ HTML + CSS + Javascript ] 复盘尝试制作 2048 小游戏时遇到的问题
  • [14]内置对象
  • [20161214]如何确定dbid.txt
  • [51nod1610]路径计数
  • [8-27]正则表达式、扩展表达式以及相关实战
  • [android]-如何在向服务器发送request时附加已保存的cookie数据
  • [Angularjs]asp.net mvc+angularjs+web api单页应用