思路一:暴力。用两个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);
}
}