首页 > 其他分享 >【剑指Offer】25、复杂链表的复制

【剑指Offer】25、复杂链表的复制

时间:2023-08-11 23:55:51浏览次数:46  
标签:25 head null Offer next 链表 pHead RandomListNode 节点

【剑指Offer】25、复杂链表的复制

题目描述:

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。

解题思路:

本题有以下三种解法:

第一种:先按照next复制,然后依次添加random指针,添加时需要定位random的位置,定位一次需要一次遍历,需要O(n^2)的复杂度。

第二种:先按照next复制,然后用一个hashmap保存原节点和复制后节点的对应关系,则用O(n)的空间复杂度使时间复杂度降到了O(n)。

第三种(最优方法):同样先按next复制,但是把复制后的节点放到原节点后面,则可以很容易的添加random,最后按照奇偶位置拆成两个链表,时间复杂度O(n),不需要额外空间。

举例:

编程实现(Java):

public class Solution {
    public RandomListNode Clone(RandomListNode pHead){
        if(pHead==null)
            return null;
        //(1)先按next复制,但是把复制后的节点放到对应原节点后面
        CopyNodes(pHead);
        //(2)依次添加random指针
        addRandom(pHead);
        //(3)按照奇偶位置拆成两个链表
        return ReconnectNodes(pHead);
    }
    //先按next复制,但是把复制后的节点放到对应原节点后面
    public void CopyNodes(RandomListNode pHead){
        RandomListNode head=pHead;
        while(head!=null){
            RandomListNode temp=new RandomListNode(head.label);
            temp.next=head.next; //复制一个结点,插在对应的原节点的后面
            temp.random=null;
            head.next=temp;
            head=temp.next;
        }
    }
    //依次添加random指针
    public void addRandom(RandomListNode pHead){
        RandomListNode head=pHead;
        while(head!=null){
            RandomListNode head_new=head.next;
            if(head.random!=null)
                head_new.random=head.random.next;
            head=head_new.next;
        }
    }
    //按照奇偶位置拆成两个链表
    public RandomListNode ReconnectNodes(RandomListNode pHead){
        if(pHead==null)
            return null;
        RandomListNode head=pHead;
        RandomListNode pHeadClone=head.next;
        RandomListNode headClone=pHeadClone;
        while(head!=null){
            head.next=headClone.next;
            head=head.next;
             if(head!=null){
                headClone.next=head.next;
                headClone=headClone.next;
             }
        }
        return pHeadClone;
    }
}

标签:25,head,null,Offer,next,链表,pHead,RandomListNode,节点
From: https://www.cnblogs.com/bujidao1128/p/17624178.html

相关文章

  • 【剑指Offer】16、合并两个排序的链表
    【剑指Offer】16、合并两个排序的链表题目描述:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。解题思路:首先需要判断几个特殊情况,即判断输入的两个指针是否为空。如果第一个链表为空,则直接返回第二个链表;如果第二个链表为空,则直接......
  • 金三银四送offer,大厂高薪,仅限50名
    又到了一年一度的金三银四求职季,不过今年实在有些诡异,已经3月下旬了,各互联网大厂不见招人,反倒有不少被爆裁员的。脉脉上每天都在更新“上午还在改Bug,下午就被HR通知走人”的恐怖故事。       尽管有些危言耸听,但也说明了目前就业形势的严峻。。。我知道关注我公号的......
  • [刷题笔记] Luogu P1725 琪露诺
    ProblemDescription若当前在\(pos\)位置,每次可以在\([pos+l,pos+r]\)区间内任选一个点跳。每跳到一个地方就可以获得这个地方的值,最后跳到位置\(pos\geqn\)即为结束,求如何跳才能使结束的时候获得的值最大?Analysis我们发现所有操作都是在一条链上完成的,显然若再次跳到这个位......
  • 剑指 Offer 13. 机器人的运动范围(中等)
    题目:classSolution{//本题的思路为递归法public:intcal(inti){//先写个计算位数和的函数calintsum=0;while(i){sum+=i%10;i/=10;}returnsum;}voidtraversal(inti,i......
  • 再论中位数:离线+链表法
    离线先得到整个序列,从最终开始倒推答案每次删掉一个数要么对中位数没有影响,要么向左/右移动一个为了确定要删除的元素在链表中的位置,使用map记录,重复删完更新向左向右可以按照删除的元素相对于中位数的位置确定,具体分类见代码#include<iostream>#include<cstdio>#include......
  • JAVA开发者最常去的25个英文网站
    -InfoIT新闻http://www.apache.org/-Apache基金会http://www.springsource.org/-广大Java开发者喜爱的Springhttp://www.hibernate.org/-开源ORM框架http://sourceforge.net/-开源技术的集结地http://www.javaalmanac.com–Java开发者年鉴一书的在线版本.......
  • PostgreSQL从小白到专家 - 第25讲:窗口函数
     PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUGPG技术大讲堂。第25讲:窗口函数内容1:窗口函数如何定义内容2:专用窗口函......
  • 《剑指Offer》-57-和为 s 的两个数字
    双指针 vector<int>twoSum(vector<int>&nums,inttarget){ //题目中说了这是一个递增数组,而且我需要两个数字组成s vector<int>res; intsmallDigit=0,bigDigit=nums.size()-1; //这要结果存在,这两个指针就不会相等 //也不能相等,相等就是同一个数字用两......
  • 《剑指Offer》-48-最长不含重复字符串的子字符串
    这题以前做过,和力扣-3重复 intlengthOfLongestSubstring(strings){ //本来应该是用map,但是其实可以使用数组替代,下标对应了字母 unordered_map<char,int>map; intlen=s.size(),maxLen=0;//初始化为0是因为可能字符串长度为0 vector<int>dp(len+1,0);//多......
  • 剑指 Offer 12. 矩阵中的路径(中等)
    题目:classSolution{public:introw,col;booltraversal(vector<vector<char>>&board,stringword,inti,intj,intk){//传入棋盘,字符串,当前棋盘元素坐标,字符串索引if(i<0||i>=row||j<0||j>=col||board[i][j]!=word[k])retu......