前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >算法练习(9)-复杂带随机指针的单链表

算法练习(9)-复杂带随机指针的单链表

作者头像
菩提树下的杨过
发布2021-10-26 10:36:03
2910
发布2021-10-26 10:36:03
举报
文章被收录于专栏:菩提树下的杨过

所谓带随机指针的链表,结构如下:

代码语言:javascript
复制
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}

除next外,还有一个随机指针random,随机指向链表中的某个元素(当然 :random也可能为null). 复制的难度在于, 新节点刚new出来时,其random指向的另外1个“新”节点,可能还没复制出来(即:首次无法确定新节点的random该指向谁,除非所有老节点全复制完)

有二种做法:

1、借助额外的Map记录“新-老”节点的映射

代码语言:javascript
复制
public Node copyRandomList(Node head) {
        if (head==null){
            return null;
        }
        Node h = head;
        Map<Node,Node> map = new HashMap<>();
        Node newHead = new Node(head.val);
        Node curr = newHead;
        //第一轮,复制节点,random挂空,同时记录处理过的老节点与新节点的映射关系
        while(head!=null){
            if (head.next!=null){
                Node newNext = new Node(head.next.val);
                curr.next = newNext;
            }
            map.put(head,curr);
            head = head.next;
            curr = curr.next;
        }
        head = h;
        //第二轮,处理random指向,通过map映射,查到random指向的新节点
        while(head!=null){
            Node newNode = map.get(head);
            if (head.random!=null){
                newNode.random = map.get(head.random);
            }
            head = head.next;
        }
        return newHead;
    }

2、如果要求空间复杂度为O(1),还有1个比较巧妙的思路

a、 先把每个节点复制一份, 挂在自己身后,相当于A -> B -> C 变成 A -> A' -> B -> B' -> C -> C'

b、 每2轮,处理random时,通过身后的“影子”,就能找到random的新节点在哪

c、 将链表分离, A -> A' -> B -> B' -> C -> C' 变成 A -> B -> C 和A' -> B' -> C' 返回A'

代码语言:javascript
复制
public Node copyRandomList(Node head) {
        if (head==null){
            return head;
        }
        Node curr = head;
        //复制自身,挂在身后
        while(curr!=null){
            Node newNode = new Node(curr.val);
            newNode.next = curr.next;
            curr.next = newNode;
            curr = curr.next.next;
        }

        //复制random
        curr = head;
        while(curr!=null){
            if (curr.random!=null){
                curr.next.random = curr.random.next;
            }
            curr = curr.next.next;
        }

        //分离链表
        curr = head;
        Node newHead = head.next;

        while(curr!=null){
            Node newCurr = curr.next;
            curr.next = curr.next.next;
            if (newCurr.next!=null){
                newCurr.next = newCurr.next.next;
            }
            curr = curr.next;
        }

        return newHead;
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-10-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档