复杂链表的复制 -- java

题目描述

请实现函数,用于复制一个复杂链表。在复杂链表中,每个结点除了有一个next指针指向下一个结点外,还有一个sibling指向链表中的任意结点或者NULL。

复杂链表如下图:
在这里插入图片描述

复杂节点定义如下:

public class ComplexListNode {
    int value;
    ComplexListNode next;

    public ComplexListNode() {
    }

    ComplexListNode sibling;

    public ComplexListNode(int value) {
        this.value = value;
    }
}

解题思路

  1. 在每个节点的后面插入复制的节点,如下图:
    在这里插入图片描述
  2. 对复制的节点的sibling指针进行赋值,如下图:
    在这里插入图片描述
    将上面的链表拆成两个链表,原始链表和复制链表,如下图:
    在这里插入图片描述

代码

public class Clone {
    public static ComplexListNode clone(ComplexListNode head) {
        cloneNodes(head);
        connectSiblingNodes(head);
        return reconnectNodes(head);
    }

    // 复制链表节点,把复制后的节点N'放在原节点N的后面
    public static void cloneNodes(ComplexListNode head) {
        while (head != null) {
            ComplexListNode cloned = new ComplexListNode();
            cloned.value = head.value;
            cloned.next = head.next;
            cloned.sibling = null;

            head.next = cloned;

            head = cloned.next;
        }
    }

    // 设置复制出来的节点的sibling
    public static void connectSiblingNodes(ComplexListNode head) {
        while (head != null) {
            ComplexListNode cloned = head.next;
            cloned.sibling = head.sibling.next;

            head = cloned.next;
        }
    }

    // 把这个长链表拆分为两个链表
    public static ComplexListNode reconnectNodes(ComplexListNode head) {
        // 复制链表的头结点
        ComplexListNode clonedHead = null;
        // 用于临时存储复制链表的节点
        ComplexListNode clonedNode = null;

        if (head != null) {
            // 设置复制链表的头结点
            clonedHead = clonedNode = head.next;
            head.next = clonedHead.next;
            head = head.next;
        }

        while (head != null) {
            clonedNode.next = head.next;
            clonedNode = clonedNode.next;
            head.next = clonedNode.next;

            head = head.next;
        }

        return clonedHead;
    }

    // 打印,用于测试
    public static void printNodes(ComplexListNode head) {
        System.out.println("head.value" + "\t" + "head.sibling.value");
        while (head != null) {
            System.out.print(head.value + "\t" + "\t" + "\t");
            if (head.random != null) {
                System.out.print(head.random.value);
            } else {
                System.out.print("null");
            }
            System.out.println();
            head = head.next;
        }
    }

    // 测试程序
    public static void main(String[] args) {
        ComplexListNode node1 = new ComplexListNode(1);
        ComplexListNode node2 = new ComplexListNode(2);
        ComplexListNode node3 = new ComplexListNode(3);

        node1.next = node2;
        node2.next = node3;

        node1.sibling = node3;
        node2.sibling = node1;
        node3.sibling = node2;

        // 复制后的链表
        ComplexListNode cloned = clone(node1);
        printNodes(cloned);
        System.out.println();

        // 不影响原链表
        printNodes(node1);
    }
}


来自:

《剑指Offer》
Coding-Interviews/复杂链表的复制.md at master · todorex/Coding-Interviews

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兔子昂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值