剑指 Offer 35. 复杂链表的复制
题目链接:https://leetcode-cn.com/problems/copy-list-with-random-pointer/
https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/
个人题解记录
1.哈希表
第一次做没想通,看了题解,意识到可以利用哈希表,遍历2次
class Solution {
public Node copyRandomList(Node head) {
Map<Node,Node> map = new HashMap<>();
Node new_node = new Node(-1);
Node tail = new_node;
Node node = head;
while (node!=null){
Node temp = new Node(node.val);
tail.next = temp;
tail = tail.next;
map.put(node,temp);
node = node.next;
}
tail = new_node.next;
node = head;
while (tail!=null){
tail.random = map.get(node.random);
tail = tail.next;
node = node.next;
}
return new_node.next;
}
}
2.哈希表+回溯
题解的思路 哈希表加回溯,访问的次数少一些,但优化不多
class Solution {
Map<Node, Node> Node = new HashMap<Node, Node>();
public Node copyRandomList(Node head) {
if (head == null) {
return null;
}
if (!Node.containsKey(head)) {
Node headNew = new Node(head.val);
Node.put(head, headNew);
headNew.next = copyRandomList(head.next);
headNew.random = copyRandomList(head.random);
}
return Node.get(head);
}
}
3.迭代
题解的思路,用于节省哈希表的开销:对于链表 A→B→C,将其复制为 A→A′→B→B′→C→C′
三次遍历:第一次复制结点,第二次处理random结点,第三次断开新旧结点的连接
public Node copyRandomList(Node head) {
if (head == null) {
return null;
}
Node node = head;
while (node!=null){
Node new_node = new Node(node.val);
new_node.next = node.next;
node.next = new_node;
node = node.next.next;
}
node = head;
while (node!=null){
Node new_node = node.next;
new_node.random = node.random!=null?node.random.next:null;
node = node.next.next;
}
node = head;
Node return_node = node.next;
while (node!=null){
Node new_node = node.next;
node.next = node.next.next;
new_node.next = new_node.next!=null?new_node.next.next:null;
node = node.next;
}
return return_node;
}