复杂链表的复制问题

题意大致是这样的:

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

分析 如果我们复制一个节点后就立即指定它的random节点可能会出现这种情况,即它的random节点还没有复制过来,这将会导致出错,故我们可以分两步进行 首先在复制链表时 先不管其random指针,在复制完成后 在从表头节点开始重新为每个节点添加random指针,具体的可以看操作过程可以看下图:

下面是具体的实现代码 :

package com.ACM;

import java.util.HashMap;


public class Solution {
    static class RandomListNode {
        int label;
        RandomListNode next = null;
        RandomListNode random = null;

        RandomListNode(int label) {
            this.label = label;
        }
    }

    public RandomListNode Clone(RandomListNode pHead) {

        RandomListNode pHead1 = pHead; //因为头结点会被反复用到,所以我们新建一个指针指向头结点
        RandomListNode cloneHead = null; //复制链表的头结点
        if (pHead == null) {   //为空直接返回
            return null;
        }
        cloneHead = new RandomListNode(pHead.label); //不为空创建头结点
        RandomListNode cloneHead1 = cloneHead;
        //先处理每个节点的next节点,进行复制 ,不要管random节点 ,
        while (pHead1.next != null) {
            RandomListNode tmp = pHead1.next;
            RandomListNode newListNode = new RandomListNode(tmp.label);
            cloneHead1.next = newListNode;
            pHead1 = tmp;
            cloneHead1 = newListNode;
        }
        //接着对链表节点中的每一个random进行处理
        //先重新获取原链表和复制链表的表头节点
        RandomListNode cloneHead2 = cloneHead;
        RandomListNode pHead2 = pHead;

        RandomListNode pheadMove = pHead;  
        RandomListNode cloneHeadMove = cloneHead;
        while (pHead2 != null && cloneHead2 != null) {
            RandomListNode tmp = pHead2.random;
            //从两个链表的头结点一起移动,当原链表移动到random
            //复制链表的头结点也移动到了该节点的random
            while (pheadMove != null && cloneHeadMove != null) {
                if (pheadMove == tmp) { //找到他的randdom节点 结束循环
                    break;
                }
                pheadMove = pheadMove.next;  //没找到 两个链表的指针都往后移
                cloneHeadMove = cloneHeadMove.next;
            }
            cloneHead2.random = cloneHeadMove;
            pheadMove = pHead; //每次都是从头结点开始寻找的
            cloneHeadMove = cloneHead;
            pHead2 = pHead2.next; //替下一个节点找它的random节点
            cloneHead2 = cloneHead2.next;
        }
        return cloneHead; //返回复制节点的头节点
    }
}







猜你喜欢

转载自blog.csdn.net/qq_32459653/article/details/81233992
今日推荐