0
点赞
收藏
分享

微信扫一扫

剑指 Offer 35. 复杂链表的复制(java实现、原地修改解法)

先来看题:

示例1:

示例2:


思考:

通过观察题目,我们会发现这个题有两种解法:

1.哈希表(不推荐)

具体代码如下:

//哈希表解法
public class Solution {
    public Node copyRandomList(Node head) {
        //先判空
        if(head == null){
            return null;
        }
        //创建一个HashMap
        Map<Node,Node> map = new HashMap<>();
        for(Node cur = head; cur != null; cur = cur.next){
            //将原节点拷贝一份放到集合中(这时只有val值相同)
            map.put(cur,new Node(cur.val));
        }
        for(Node cur = head; cur != null;cur = cur.next){
            //通过next值将所有拷贝的节点连接到一起
            map.get(cur).next = map.get(cur.next);
            //拷贝原节点中random的值
            map.get(cur).random = map.get(cur.random);
        }
        //返回原节点作为键时所对应的新链表的头节点
        return map.get(head);
    }
}

LeetCode上测试:

 


第二种解法就是:原地修改解法(推荐)

相较于哈希表,我感觉这种解法更能体现我们的代码能力,所以我也推荐用此方法

原理:

大体结构:

 详细步骤:

具体代码:

class Solution {
    public Node copyRandomList(Node head) {
        //先判空链表
        if (head == null) {
            return null;
        }
        //不直接使用head,备份一个cur
        Node cur = head;
        //遍历链表
        while (cur != null) {
            //创建一个新节点,使它的val值与原节点的val值相等
            Node node = new Node(cur.val);
            //将新节点连接到原节点后面
            node.next = cur.next;
            cur.next = node;
            //处理下一个原节点
            cur = cur.next.next;
        }
        //重置一下cur
        cur = head;
        //遍历
        while (cur != null) {
            //判断一下原节点的random是不是null
            //不是,就进行处理
            //由于新创建节点的random值默认是null,所以不用管
            if (cur.random != null) {
                //不是,就将原节点的random指向也拷贝到新节点的random中
                //这里需要注意:
                //cur.random是原节点的值,新节点不能直接指向
                //所以只能指向那个原节点的拷贝节点
                //在上面我们就已经将每个拷贝节点放到了每个原节点的后面
                cur.next.random = cur.random.next;
            }
            //处理下一个
            cur = cur.next.next;
        }
        //存放新链表的头节点
        Node copyHead = head.next;
        cur = head;
        //拷贝一份用来循环遍历
        Node copyCur = head.next;
        while (cur != null) {
            //连接原链表
            cur.next = cur.next.next;
            cur = cur.next;
            //判断是不是尾结点
            if (copyCur.next != null) {
                //不是,继续连接新链表
                copyCur.next = copyCur.next.next;
                copyCur = copyCur.next;
            }
        }
        //返回新链表的头节点
        return copyHead;
    }
}

LeetCode上测试:

 总结:

方法有两种,哈希表与原地修改法没有谁一定好,谁一定坏,但是一般在面试中还是推荐用原地修改法。

举报

相关推荐

0 条评论