解题思路:
1、利用哈希表的查询特点,考虑构建 原链表节点 和 新链表对应节点 的键值对映射关系,再遍历构建新链表各节点的 next 和 random 引用指向即可
2、考虑构建 原节点 1 -> 新节点 1 -> 原节点 2 -> 新节点 2 -> …… 的拼接链表,如此便可在访问原节点的 random 指向节点的同时找到新对应新节点的 random 指向节点。
具体步骤:
复制各节点,构建拼接链表:设原链表为 node1→node2→⋯ ,构建的拼接链表如下所示:
node1→node1_new→node2→node2_new →
构建新链表各节点的 random 指向:当访问原节点 cur 的随机指向节点 cur.random 时,对应新节点 cur.next 的随机指向节点为 cur.random.next 。
拆分原 / 新链表:设置 pre / cur 分别指向原 / 新链表头节点,遍历执行 pre.next = pre.next.next 和 cur.next = cur.next.next 将两链表拆分开。
返回新链表的头节点 res 即可。
举例说明:
具体步骤:
复制各节点,构建拼接链表:设原链表为 node1→node2→⋯ ,构建的拼接链表如下所示:
node1→node1_new→node2→node2_new →
构建新链表各节点的 random 指向:当访问原节点 cur 的随机指向节点 cur.random 时,对应新节点 cur.next 的随机指向节点为 cur.random.next 。
拆分原 / 新链表:设置 pre / cur 分别指向原 / 新链表头节点,遍历执行 pre.next = pre.next.next 和 cur.next = cur.next.next 将两链表拆分开。
返回新链表的头节点 res 即可。
举例说明:
复杂链表:{1,2,3,4,5,3,5,#,2,#}
(1)初始化哈希表dict,节点cur指向头节点
(2)复制链表;建立新节点,循环遍历链表,并向 dict 添加键值对 (原 cur 节点, 新 cur 节点)
(3)构建新链表的引用指向;cur遍历原链表,构建新节点的next、random引用指向
(4)返回新链表的头节点 dict[pHead]
图解:
代码:
Python版本:
# -*- coding:utf-8 -*-
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# write code here
if not pHead:
return None
# 利用字典保存新旧链表节点的对应关系
dict = {}
cur = pHead
# 建立新的链表节点 字典
while cur:
dict[cur] = RandomListNode(cur.label)
cur = cur.next
# 建立新节点的关联字典
cur = pHead
while cur:
dict[cur].next = dict.get(cur.next)
dict[cur].random = dict.get(cur.random)
cur = cur.next
return dict[pHead] JAVA版本: import java.util.Map;
import java.util.HashMap;
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public RandomListNode Clone(RandomListNode pHead){
if(pHead == null) return null;
RandomListNode cur = pHead;
Map<randomlistnode> map = new HashMap<>();
// 3. 复制各节点,并建立 “原节点 -> 新节点” 的 Map 映射
while(cur != null) {
map.put(cur, new RandomListNode(cur.label));
cur = cur.next;
}
cur = pHead;
// 4. 构建新链表的 next 和 random 指向
while(cur != null) {
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
cur = cur.next;
}
// 5. 返回新链表的头节点
return map.get(pHead);
}
}</randomlistnode> 复杂度分析:
时间复杂度 O(N): 两轮遍历链表,使用 O(N) 时间。
空间复杂度 O(N) : 哈希表 dict 使用线性大小的额外空间



京公网安备 11010502036488号