剑指offer 48. 复杂链表的复刻-java详细图解

Acwing 48. 复杂链表的复刻

原题链接

请实现一个函数可以复制一个复杂链表。

在复杂链表中,每个结点除了有一个指针指向下一个结点外,还有一个额外的指针指向链表中的任意结点或者null。

注意:

函数结束后原链表要与输入时保持一致。
数据范围
链表长度 [0,500]。

代码案例:

题解

在这里插入图片描述
哈希表做法和更加巧妙的解法
主要思路是通过复制链表的方式,来解决random节点的查找问题。大体可以分为三步:

  1. 链表所有节点中间都插入一个复制节点,作为并行链表
  2. 遍历新链表,遇到Random节点后对应改变并行链表中的节点
  3. 提取出并行链表
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

写法精简一点

 public ListNode copyRandomList(ListNode head) {
        if(head == null){
            return null;
        }
        for(ListNode cur = head; cur != null; cur = cur.next.next){
            ListNode temp = new ListNode(cur.val);
            temp.next = cur.next;
            cur.next = temp;
        }
        for(ListNode cur = head; cur != null; cur = cur.next.next){
            if(cur.random == null){
                continue;
            }
            cur.next.random = cur.random.next;
        }
        ListNode newHead = new ListNode(-1);
        for(ListNode cur = head, cur1 = newHead; cur != null; cur = cur.next){
            cur1.next = cur.next;
            cur1 = cur1.next;
            cur.next = cur.next.next;
        }
        return newHead.next;
    }
 
/**
 * Definition for singly-linked list with a random pointer.
 * class ListNode {
 *     int val;
 *     ListNode next, random;
 *     ListNode(int x) { this.val = x; }
 * };
 */
class Solution {
    public ListNode copyRandomList(ListNode head) {
        //第一步 复制原来的结点 在每个结点的后面
         ListNode p ;
        for(   p = head ; p != null ;p=p.next.next){
            ListNode t = new ListNode(p.val);
            ListNode tt = p.next ;//复制结点的时候留存p.next结点 要不动用p.next 会导致结果为空
            p.next = t ;
            t.next = tt ;
          // p = tt;//如果是p = p.next 的话那么p就是代替的是复制的t结点了 而我们是要遍历原来的结点 要替代原来的结点
           //或者改成p = p.next.next
        } 
       
        //第二步 random指向
         p = head ; 
      while( p != null  ){
            if(p.random != null)
            p.next.random = p.random.next;
             p = p.next.next;
        }
        
        //第三步 遍历结点  要把复制结点拎出来
         ListNode dummy = new ListNode(-1);
        ListNode cur = dummy;
        //dummy.next = head ;
        for(  p = head ; p != null ; p = p.next){
            cur.next = p.next ;
            cur = cur.next ;//把cur 往后移一个位置
            p.next =p.next.next ;//p.next 往后移一个位置
        }
        return dummy.next;
    }
}

借助HashMap[HTML_REMOVED],key= 以前的结点 value = 新复制的结点
先从前往后将链表复制出来,再一一修改其random指针。

 public ListNode copyRandomList(ListNode head) {
        if(head == null){
            return null;
        }
        Map<ListNode, ListNode> map = new HashMap<>(); // key = old value = new
        ListNode newHead = new ListNode(head.val);
        map.put(head, newHead);
        for(ListNode cur1 = head, cur2 = newHead; cur1.next != null; cur1 = cur1.next, cur2 = cur2.next){
            cur2.next = new ListNode(cur1.next.val);
            map.put(cur1.next, cur2.next);
        }
        for(ListNode cur1 = head, cur2 = newHead; cur1 != null; cur1 = cur1.next, cur2 = cur2.next){
            if(cur1.random == null){
                continue;
            }
            cur2.random = map.get(cur1.random);
        }
        return newHead;
    }

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

依嘫_吃代码

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

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

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

打赏作者

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

抵扣说明:

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

余额充值