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

思路一:暴力。用两个Node型的动态数组ArrayList,一个为temp,另一个为res,temp存放原链表的每一个节点,res存放复制过来的每一个节点(节点中next指针域和random指针域都没有赋值),然后遍历res,给res中每一个节点的next指针域和random指针域赋值。时间复杂度O(N),空间复杂度O(N)。

class Solution {
    private List<Node> temp = new ArrayList<>();
    private List<Node> res = new ArrayList<>();
    public Node copyRandomList(Node head) {
        while (head != null) {
            Node node = new Node(head.val);
            temp.add(head);
            res.add(node);
            head = head.next;
        }
        for (int i = 0; i < res.size(); i ++) {
            res.get(i).random = (temp.get(i).random == null ? null : res.get(temp.indexOf(temp.get(i).random)));
            if (i != res.size() - 1) {
                res.get(i).next = res.get(i + 1);
            }
        }
        return res.size() == 0 ? null : res.get(0);
    }
}

思路二:其实思路一用两个动态数组来存放新的复制链表中random节点与原链表的节点的对应关系。可以用一个哈希结构来替换两个动态数组。时间复杂度O(N),空间复杂度O(N)。

class Solution {
    private Map<Node, Node> map = new HashMap<>();
    public Node copyRandomList(Node head) {
        Node cur = head;
        Node dummyNewHead = new Node(-1);
        Node newCur = dummyNewHead;
        while (cur != null) {
            Node node = new Node(cur.val);
            map.put(cur, node);
            newCur.next = node;
            newCur = newCur.next;
            cur = cur.next;
        }
        cur = head;
        newCur = dummyNewHead.next;
        while (cur != null) {
            newCur.random = map.get(cur.random);
            newCur = newCur.next;
            cur = cur.next;
        }
        return dummyNewHead.next;
    }
}

思路三:解决本题的核心就是要知道新链表中每一个节点random节点在新链表的位置。直接在原链表上复制每一个节点在原节点的后面(复制操作),1->2->3复制后为1->1->2->2->3->3。再让新的复制节点的random的指针域指向原节点指针的下一个节点,最后把新链表从原链表拆分出来。(拆分操作)时间复制度O(N),空间复杂度O(1)(返回的结果链表不计入)。

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) {
            return head;
        }
        Node cur = head;
        while (cur != null) {
            Node node = new Node(cur.val);
            node.next = cur.next;
            cur.next = node;
            cur = cur.next.next;
        }
        cur = head;
        while (cur != null) {
            Node temp = cur.next.next;
            cur.next.random = (cur.random == null ? null : cur.random.next);
            cur = cur.next.next;
        }
        cur = head;
        Node res = cur.next;
        while (cur != null) {
            Node node = cur.next;
            cur.next = cur.next.next;
            node.next = (node.next == null ? null: node.next.next);
            cur = cur.next;
        }
        return res;
    }
}

思路四:思路二是哈希+迭代实现。可以用哈希+递归实现。

class Solution {
    private Map<Node, Node> map = new HashMap<>();
    public Node copyRandomList(Node head) {
        if (head == null) {
            return head;
        }
        if (!map.containsKey(head)) {
            Node node = new Node(head.val);
            map.put(head, node);
            node.next = copyRandomList(head.next);
            node.random = copyRandomList(head.random);
        }
        return map.get(head);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值