深度拷贝带随机指针的链表代码2优化

深度拷贝带随机指针的链表代码2优化

使用HasnMap的方式

深度拷贝带随机指针的链表代码1

不使用HashMap的方式

深度拷贝带随机指针的链表:
时间复杂度:O(n),虽然有两个循环,但是没有嵌套,因此是O(2n) => O(n)
空间复杂度:O(n),因为用到了hashmap来存储random指针,深拷贝,因此拷贝所占用的空间不计

因此优化成不使用HashMap的方式

public class Test2 {

    public static class ListNode {
        Object value;
        ListNode next;
        ListNode random;

        public ListNode(Object value, ListNode next, ListNode random) {
            this.value = value;
            this.next = next;
            this.random = random;
        }

        public ListNode(Object value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return "ListNode{" +
                    "value=" + value +
                    ", next=" + next +
                    ", random=" + random +
                    '}';
        }

        public void setRandom(ListNode random) {
            this.random = random;
        }
    }

    /**
     * 深度拷贝带随机指针的链表
     *
     * @param head
     * @return
     */
    public static ListNode copyRandomList(ListNode head) {
        if (head == null) {//规范的代码都会做防空判断
            return head;
        }
        copyValue(head);
        copyRandom(head);
        return split(head);
    }

    /**
     * 复制链表value
     * 原链表node(n) next指向复制后的node(n`),复制后的node(n`) next指向node(n+1),n为下标
     *
     * @param head
     */
    public static void copyValue(ListNode head) {
        ListNode node = head;
        while (node != null) {
            ListNode copy = new ListNode(node.value);
            copy.next = node.next;
            node.next = copy;
            node = copy.next;
        }
    }

    /**
     * 复制链表random
     * 原链表node(n) next指向复制后的node(n`),复制后的node(n`) next指向node(n+1),n为下标,根据对应next 来copy random
     *
     * @param head
     */
    private static void copyRandom(ListNode head) {
        ListNode node = head;
        while (node != null && node.next != null) {
            if (node.random != null) {
                node.next.random = node.random.next;
            }
            node = node.next.next;
        }
    }

    /**
     * 拆分
     * 原链表node(n) next指向复制后的node(n`),复制后的node(n`) next指向node(n+1),n为下标,根据next next来进行拆分
     *
     * @param head
     * @return
     */
    private static ListNode split(ListNode head) {
        ListNode result = head.next;//head.next就是拷贝后的头节点,即1`
        ListNode move = head.next;
        while (head != null && head.next != null) {
            head.next = head.next.next;
            head = head.next;
            if (move != null && move.next != null) {
                move.next = move.next.next;
                move = move.next;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        ListNode node6 = new ListNode(66, null, null);
        ListNode node5 = new ListNode(55, node6, null);
        ListNode node4 = new ListNode(44, node5, null);
        ListNode node3 = new ListNode(33, node4, node5);
        ListNode node2 = new ListNode(22, node3, null);
        ListNode node1 = new ListNode(11, node2, node6);
//        node6.setRandom(node1);//toString会死循环,因此不加,已经可以完成深度拷贝

        System.out.println(node1);//ListNode{value=11, next=ListNode{value=22, next=ListNode{value=33, next=ListNode{value=44, next=ListNode{value=55, next=ListNode{value=66, next=null, random=null}, random=null}, random=null}, random=ListNode{value=55, next=ListNode{value=66, next=null, random=null}, random=null}}, random=null}, random=ListNode{value=66, next=null, random=null}}
        ListNode copyRandomList = copyRandomList(node1);
        System.out.println(copyRandomList);//ListNode{value=11, next=ListNode{value=22, next=ListNode{value=33, next=ListNode{value=44, next=ListNode{value=55, next=ListNode{value=66, next=null, random=null}, random=null}, random=null}, random=ListNode{value=55, next=ListNode{value=66, next=null, random=null}, random=null}}, random=null}, random=ListNode{value=66, next=null, random=null}}
    }

}

图解

请添加图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用哈希表来实现对随机指针链表进行复刻。具体步骤如下: 1. 遍历原链表,将每个节点都复制一份,并将复制的节点插入到原节点的后面,形成一个新的链表。 2. 再次遍历原链表,将每个新节点的随机指针指向原节点随机指针的下一个节点。 3. 将新链表拆分成两个链表,一个是原链表的复制,一个是新链表的复制。 下面是Python代码实现: ```python class Node: def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): self.val = int(x) self.next = next self.random = random class Solution: def copyRandomList(self, head: 'Node') -> 'Node': if not head: return None # 第一次遍历,复制节点并插入到原节点后面 cur = head while cur: node = Node(cur.val, cur.next) cur.next = node cur = node.next # 第二次遍历,处理随机指针 cur = head while cur: if cur.random: cur.next.random = cur.random.next cur = cur.next.next # 第三次遍历,拆分链表 cur = head new_head = head.next while cur.next: tmp = cur.next cur.next = tmp.next cur = tmp return new_head ``` 注释: 1. 定义一个Node类,表示链表节点,包含三个属性:值val、下一个节点next、随机指针random。 2. 定义一个Solution类,包含一个方法copyRandomList,用于复刻随机指针链表。 3. 第一次遍历原链表,复制每个节点并插入到原节点的后面,形成一个新的链表。 4. 第二次遍历原链表,处理每个新节点的随机指针,使其指向原节点随机指针的下一个节点。 5. 第三次遍历原链表,拆分新链表和原链表的复制。 6. 返回新链表的头节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值