面试题35_复杂链表的复制

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

题解一

使用哈希表保存原链表和复制后链表的指针。

  1. 第一个遍历将原链表的next指针复制一遍,同时保存对应的指针(确保原链表中的每一个节点都能在复制后链表中找到)。
  2. 第二个遍历将原链表的random指针复制一遍(从哈希表中取对应节点)。

时间复杂度为O(n),空间复杂度为O(n)。

public RandomListNode Clone(RandomListNode head) {
    if (head == null)
        return null;
    RandomListNode headClone = new RandomListNode(head.label);
    HashMap map = new HashMap<>();
    map.put(head, headClone);

    // 第一个遍历复制next指针
    RandomListNode p = head.next;
    RandomListNode pClone = headClone;
    while (p != null) {
        pClone.next = new RandomListNode(p.label);
        pClone = pClone.next;
        map.put(p, pClone);
        p = p.next;
    }
    
    // 第二个遍历复制random指针
    p = head;
    pClone = headClone;
    while (p != null) {
        if (p.random != null)
            pClone.random = map.get(p.random);
        p = p.next;
        pClone = pClone.next;
    }
    return headClone;
}

题解二

  1. 在原链表的每个节点后都添加一个节点作为复制后的节点。
  2. 给复制后的节点添加random指针。
  3. 把第二步得到的链表拆分成两个链表。

时间复杂度为O(n),空间复杂度为O(1)。

public RandomListNode Clone(RandomListNode head) {
    if (head == null)
        return null;

    // 1.在原链表的每个节点后都添加一个节点作为复制后的节点。
    RandomListNode p = head;
    RandomListNode r;
    while (p != null) {
        r = new RandomListNode(p.label);
        r.next = p.next;
        p.next = r;
        p = r.next;
    }

    // 2.添加random指针。
    p = head;
    while (p != null) {
        if (p.random != null)
            p.next.random = p.random.next;
        p = p.next.next;
    }

    // 3.拆分两个链表。
    p = head;
    r = head.next;
    RandomListNode headClone = r;
    while (p != null) {
        p.next = p.next.next;
        if (r != null && r.next != null)
            r.next = r.next.next;
        p = p.next;
        r = r.next;
    }
    return headClone;
}

你可能感兴趣的:(面试题35_复杂链表的复制)