剑指offer-JZ35 复杂链表的复制

较难 通过率:23.51% 时间限制:1秒 空间限制:64M
知识点
链表
描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。 下图是一个含有5个结点的复杂链表。图中实线箭头表示next指针,虚线箭头表示random指针。为简单起见,指向null的指针没有画出。
在这里插入图片描述示例:
输入:{1,2,3,4,5,3,5,#,2,#}
输出:{1,2,3,4,5,3,5,#,2,#}
解析:我们将链表分为两段,前半部分{1,2,3,4,5}为ListNode,后半部分{3,5,#,2,#}是随机指针域表示。
以上示例前半部分可以表示链表为的ListNode:1->2->3->4->5
后半部分,3,5,#,2,#分别的表示为
1的位置指向3,2的位置指向5,3的位置指向null,4的位置指向2,5的位置指向null
如下图:
在这里插入图片描述
示例1

输入:
{1,2,3,4,5,3,5,#,2,#}
返回值:
{1,2,3,4,5,3,5,#,2,#}

解题思路
复制每一个节点,并存入数组。其余直接看代码。可以用循环去做,不过我想练练递归。

/**
 * struct RandomListNode {
 *  int label;
 *  struct RandomListNode *next;
 *  struct RandomListNode *random;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param pHead RandomListNode类
 * @return RandomListNode类
 */
struct RandomListNode* Clone(struct RandomListNode* pHead ) {
    // write code here
    struct RandomListNode* f(struct RandomListNode * pHead,
                             struct RandomListNode * flag[]);
    struct RandomListNode* flag[1001] = {NULL};
    return f(pHead, flag);
}
struct RandomListNode* f(struct RandomListNode* pHead,
                         struct RandomListNode* flag[]) {
    if (flag[pHead->label] || !pHead) return NULL;
    // write code here
    struct RandomListNode* result = (struct RandomListNode*)malloc(sizeof(
                                        struct RandomListNode));
    flag[pHead->label] = result;
    result->next = NULL;
    result->random = NULL;
    result->label = pHead->label;
    if (pHead->next) {
        result->next = f(pHead->next, flag);
    }
    if (pHead->random) {
        if (flag[pHead->random->label]) {
            result->random = flag[pHead->random->label];
        } else {
            result->random = f(pHead->random, flag);
        }
    }

    return result;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值