剑指offer复杂链表复制

题目描述

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

我的代码,思路比较笨,就是首先构造一个正常的不大random指针的链表,然后再去遍历原始链表,查看random指针指向的位置,同时移动复制的链表的next,找到后赋值。时间复杂度比较大O(n^2)

public class Solution {
    public RandomListNode Clone(RandomListNode pHead)
    {
        RandomListNode head2 = null ;
        RandomListNode cur = head2;
        RandomListNode tmp = pHead;
        while(tmp!=null){
            RandomListNode node = new RandomListNode(tmp.label);
            if(cur == null)
                cur = head2 = node;
            else
           {
                cur.next = node;
                cur = node;
            }
            tmp = tmp.next;

        }
        cur = head2;
        tmp = pHead;
        while(cur!=null){

            RandomListNode tmp1 = pHead;
            RandomListNode tmp2 = head2;
            while(tmp.random != tmp1&&tmp1!=null){
                tmp1 = tmp1.next;
                tmp2 = tmp2.next;
            }
            tmp = tmp.next;
            cur.random = tmp2;
            cur = cur.next;
        }

        return head2;
    }
}

优秀代码,c++写的,忽略语言,看疗效,首先将复制的节点插入到对应的原始节点的后面,这样组成了一个复制节点和原始节点混合的链表,此时链表上除了原始链表节点上的random有指向外,新生成的节点random均为空。下一步就是补齐random节点,利用新旧节点混合在一起的优势,可以很快找到新节点的random指针的指向。最后,没隔一个拆分开。得到原始节点。时间复杂度O(n)。画了张图,将就着看吧。找到红色的random指向后,绿色的也就很容易找到了。
这里写图片描述

class Solution {
public:
    /*
        1、复制每个节点,如:复制节点A得到A1,将A1插入节点A后面
        2、遍历链表,A1->random = A->random->next;
        3、将链表拆分成原链表和复制后的链表
    */

    RandomListNode* Clone(RandomListNode* pHead)
    {
        if(!pHead) return NULL;
        RandomListNode *currNode = pHead;
        while(currNode){
            RandomListNode *node = new RandomListNode(currNode->label);
            node->next = currNode->next;
            currNode->next = node;
            currNode = node->next;
        }
        currNode = pHead;
        while(currNode){
            RandomListNode *node = currNode->next;
            if(currNode->random){               
                node->random = currNode->random->next;
            }
            currNode = node->next;
        }
        //拆分
        RandomListNode *pCloneHead = pHead->next;
        RandomListNode *tmp;
        currNode = pHead;
        while(currNode->next){
            tmp = currNode->next;
            currNode->next =tmp->next;
            currNode = tmp;
        }
        return pCloneHead;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值