菜鸟笔记
提升您的技术认知

剑指offer

《剑指offer》刷题目笔记

剑指offer 数组

《剑指offer》二维数组中的查找《剑指offer》旋转数组的最小数字《剑指offer》调整数组顺序使奇数位于偶数前面《剑指offer》数组中出现次数超过一半的数字《剑指offer》连续子数组的最大和《剑指offer》把数组排成最小的数《剑指offer》数组中的逆序对《剑指offer》数字在排序数组中出现的次数《剑指offer》数组中只出现一次的数字《剑指offer》数组中重复的数字《剑指offer》构建乘积数组

剑指offer 字符串

《剑指offer》替换空格《剑指offer》字符串的排列《剑指offer》第一个只出现一次的字符《剑指offer》左旋转字符串《剑指offer》翻转单词顺序序列《剑指offer》把字符串转换成整数《剑指offer》正则表达式匹配《剑指offer》表示数值的字符串

剑指offer 链表

《剑指offer》从尾到头打印链表《剑指offer》链表中倒数第k个结点《剑指offer》反转链表《剑指offer》合并两个排序的链表《剑指offer》复杂链表的复制《剑指offer》两个链表的第一个公共结点《剑指offer》链表中环的入口结点《剑指offer》删除链表中重复的结点

剑指offer 树

《剑指offer》重建二叉树《剑指offer》树的子结构《剑指offer》二叉树的镜像《剑指offer》从上往下打印二叉树《剑指offer》二叉树中和为某一值的路径《剑指offer》二叉树的深度《剑指offer》平衡二叉树《剑指offer》二叉树的下一个结点《剑指offer》对称的二叉树《剑指offer》按之字顺序打印二叉树《剑指offer》把二叉树打印成多行《剑指offer》序列化二叉树

《剑指offer》复杂链表的复制-ag真人游戏

阅读 : 176

题目描述

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

解题思路

大部分人首先想到的可能是先复制复杂指针的label和next,然后再查找random并更新。查找random又分为两种,一种是每次都从头查找,时间复杂度为o(n^2);另一种是空间换时间,复制label和next的同时建立一个hash表来存放新旧复杂指针的对应关系,所以后续只需一步就能找到random,算法时间复杂度为o(n)。

我们这里将复杂链表的复制过程分解为三个步骤。在写代码的时候我们每一步定义一个函数,这样每个函数完成一个功能,整个过程的逻辑也就非常清晰明了了。

我们这里采用三步:

第一步:复制复杂指针的label和next。但是这次我们把复制的结点跟在元结点后面,而不是直接创建新的链表;
第二步:设置复制出来的结点的random。因为新旧结点是前后对应关系,所以也是一步就能找到random;
第三步:拆分链表。奇数是原链表,偶数是复制的链表。
有图思路更清晰:

代码实现(c )

/*
struct randomlistnode {
    int label;
    struct randomlistnode *next, *random;
    randomlistnode(int x) :
            label(x), next(null), random(null) {
    }
};
*/
class solution {
public:
    //第一步,复制复杂指针的label和next
    void clonenodes(randomlistnode* phead){
        randomlistnode* pnode = phead;
        while(pnode != null){
            randomlistnode* pcloned = new randomlistnode(0);
            pcloned->label = pnode->label;
            pcloned->next = pnode->next;
            pcloned->random = null;
            pnode->next = pcloned;
            pnode = pcloned->next;
        }
    }
    //第二步,处理复杂指针的random
    void connectsiblingnodes(randomlistnode* phead){
        randomlistnode* pnode = phead;
        while(pnode != null){
            randomlistnode* pcloned = pnode->next;
            if(pnode->random != null){
                pcloned->random = pnode->random->next;
            }
            pnode = pcloned->next;
        }
    }
    //第三步,拆分复杂指针
    randomlistnode* reconnectnodes(randomlistnode* phead){
        randomlistnode* pnode = phead;
        randomlistnode* pclonedhead = null;
        randomlistnode* pclonednode = null;
        if(pnode != null){
            pclonedhead = pclonednode = pnode->next;
            pnode->next = pclonednode->next;
            pnode = pnode->next;
        }
        while(pnode != null){
            pclonednode->next = pnode->next;
            pclonednode = pclonednode->next;
            pnode->next = pclonednode->next;
            pnode = pnode->next;
        }
        return pclonedhead;
    }
    randomlistnode* clone(randomlistnode* phead)
    {
        clonenodes(phead);
        connectsiblingnodes(phead);
        return reconnectnodes(phead);
    }
};
网站地图