剑指 Offer 35. 复杂链表的复制 LeetCode

LeetCode原题地址:剑指 Offer 35. 复杂链表的复制
思路:先复制next,再复制random

/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/
class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        // 新链表的第一个结点的前一个结点,复制过程中需要使用,返回的是newHead.next
        Node newHead = new Node(-1);
        newHead.next = null;
        newHead.random = null;
        // 一个尾指针指向新链表的尾部,正向建链表过程中需要用到
        Node newTail = newHead;
        Node temp = head;
        // 本次遍历只复制next域,相当于正向建立链表的过程
        while (temp != null) {
            Node node = new Node(temp.val);
            node.next = null;
            node.random = null;
            newTail.next = node;
            newTail = node;
            temp = temp.next;
        }
        // 重新让temp指向head位置,下面的遍历过程需要原链表和新链表同时遍历同样的位
        // 置(即两个指针各自指向自己的第一个、第二个,一直遍历到最后一个结点)
        temp = head;
        Node keyTemp = newHead.next;        
        while (temp != null && keyTemp != null) {
        	// 一个标志,用于标记当前访问结点的random域是指向了当前链表的其他结点还是null
            boolean flag = false;
            int count = 0;
            // 如果当前结点的random域不是null,那么count用来记录random域指向了当前链表的第几个结点
            if (temp.random != null) {
                flag = true;
                count = 0;
                Node newTemp = head;
                // 从头遍历原链表,找到当前结点random域指向的位置
                while (newTemp != null) {
                    count++;
                    if (newTemp == temp.random) {
                        break;
                    }
                    newTemp = newTemp.next;
                }
            }
            // 根据flag标记的不同,复制新链表中对应结点的random域时做不同的操作
            // flag为true,那么需要找到新链表中的第count个结点,并把新链表中当前结点对应结点的random域指向该结点
            if (flag) {
                int cnt = 0;
                Node curRandom = newHead.next;
                while (curRandom != null) {
                    cnt++;
                    if (cnt == count) {
                        break;
                    }
                    curRandom = curRandom.next;
                }
                keyTemp.random = curRandom;
            } else { // flag为false,那么新链表中当前结点对应结点的random域为null
                keyTemp.random = null;
            }
            temp = temp.next;
            keyTemp = keyTemp.next;
        }
        return newHead.next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值