【中等】复制含有随机指针节点的链表-Java:普通解法

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击人工智能教程

package live.every.day.ProgrammingDesign.CodingInterviewGuide.List;

import java.util.HashMap;

/**
 * 复制含有随机指针节点的链表
 *
 * 【题目】
 * 一种特殊的链表节点类描述如下:
 * public class Node{
 * public int data;
 * public Node next;
 * public Node rand;
 * public Node (int data){
 * this.data=data;
 * }
 * }
 * Node类中的data是节点数据,next指针和正常单链表中next指针的意义一样,都指向下一个节点,rand指针是Node类中新增的指
 * 针,这个指针可能指向链表中的任意一个节点,也可能指向null。
 * 给定一个由Node节点类型组成的无环单链表的头节点head,请实现一个函数完成这个链表中所有结构的复制,并返回复制的新链表的
 * 头节点。
 *
 * 【难度】
 * 中等
 *
 * 【解法】
 * 首先介绍普通解法,普通解法可以做到时间复杂度为O(N),额外空间复杂度为O(N),需要使用到哈希表(HashMap)结构。具体过程
 * 如下:
 * 1、首先从左到右遍历链表,对每个节点都复制生成相应的副本节点,然后将对应关系放入哈希表map中。步骤1完成后,原链表没有
 * 任何变化,每一个副本节点的next和rand指针都指向null。
 * 2、再从左到右遍历链表,此时就可以设置每一个副本节点的next和rand指针。
 * 3、将第1个副本节点作为结果返回即可。
 * 哈希表增删改查的操作时间复杂度都是O(1),普通方法一共只遍历链表两遍,所以普通解法的时间复杂度为O(N),因为使用了哈希表
 * 来保存原节点与副本节点的对应关系,所以额外空间复杂度为O(N)。
 * 具体过程请参看如下代码中的copyListWithRand1方法。
 *
 * @author Created by LiveEveryDay
 */

public class CopyRandomPointerNodeList1 {

    public static class Node {
        public int data;
        public Node next;
        public Node rand;

        public Node(int data) {
            this.data = data;
        }
    }

    public static Node copyListWithRand1(Node head) {
        HashMap<Node, Node> map = new HashMap<>();
        Node cur = head;
        while (cur != null) {
            map.put(cur, new Node(cur.data));
            cur = cur.next;
        }
        cur = head;
        while (cur != null) {
            map.get(cur).next = map.get(cur.next);
            map.get(cur).rand = map.get(cur.rand);
            cur = cur.next;
        }
        return map.get(head);
    }

    public static void main(String[] args) {
        Node node1 = new Node(1);
        Node node2 = new Node(2);
        Node node3 = new Node(3);
        node1.next = node2;
        node2.next = node3;
        node3.next = null;
        node1.rand = node3;
        node2.rand = node2;
        node3.rand = node1;
        Node head = copyListWithRand1(node1);
        Node cur = head;
        while (cur != null) {
            System.out.printf("%d ", cur.data);
            cur = cur.next;
        }
        System.out.println();
        cur = head;
        while (cur != null) {
            System.out.printf("%d ", cur.rand.data);
            cur = cur.next;
        }
    }

}

// ------ Output ------
/*
1 2 3
3 2 1
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值