主题
题意
深拷贝一个链表,要求新链表中的每个节点都是新创建的,并且这些节点的
思路
如果没有
有
所以必须记录原链表节点到新链表节点的映射(map)。这样可以通过原链表
难道要用哈希表吗?不需要,我们可以把新链表和旧链表「混在一起」。
例如链表
如此一来,原链表节点的下一个节点,就是其对应的新链表节点了!
然后遍历这个交错链表,假如节点
最后,从交错链表中分离出
⚠注意:不能只删除节点
python
class Solution:
def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
# 复制每个节点,把新节点直接插到原节点的后面
cur = head
while cur:
cur.next = Node(cur.val, cur.next)
cur = cur.next.next
# 遍历交错链表中的原链表节点
cur = head
while cur:
if cur.random:
# 要复制的 random 是 cur.random 的下一个节点
cur.next.random = cur.random.next
cur = cur.next.next
# 删除交错链表中的原链表节点,剩下的节点即为新链表
cur = dummy = Node(0, head)
while cur.next:
# 删除原链表的节点,即当前节点的下一个节点
# 如果要恢复原链表,见另一份代码【Python3 写法二】
cur.next = cur.next.next
cur = cur.next
return dummy.nextcpp
// C++ 版待补充python
class Solution:
def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
# 复制每个节点,把新节点直接插到原节点的后面
cur = head
while cur:
cur.next = Node(cur.val, cur.next)
cur = cur.next.next
# 遍历交错链表中的原链表节点
cur = head
while cur:
if cur.random:
# 要复制的 random 是 cur.random 的下一个节点
cur.next.random = cur.random.next
cur = cur.next.next
# 把交错链表分离成两个链表
tail = dummy = Node(0, head)
cur = head
while cur:
copy = cur.next # 新节点
tail.next = copy # 把新节点插在 tail 的后面,构建新的链表
cur.next = copy.next # 恢复原节点的 next
cur = cur.next
tail = tail.next
return dummy.nextcpp
// C++ 版待补充cpp
class Solution {
public:
Node* copyRandomList(Node* head) {
// 复制每个节点,把新节点直接插到原节点的后面
for (Node* cur = head; cur; cur = cur->next->next) {
cur->next = new Node(cur->val, cur->next, nullptr);
}
// 遍历交错链表中的原链表节点
for (Node* cur = head; cur; cur = cur->next->next) {
if (cur->random) {
// 要复制的 random 是 cur->random 的下一个节点
cur->next->random = cur->random->next;
}
}
// 把交错链表分离成两个链表
Node dummy(0);
Node* tail = &dummy;
for (Node* cur = head; cur; cur = cur->next, tail = tail->next) {
Node* copy = cur->next; // 新节点
tail->next = copy; // 把新节点插在 tail 的后面,构建新的链表
cur->next = copy->next; // 恢复原节点的 next
}
return dummy.next;
}
};复杂度分析
- 时间复杂度:
,其中 是链表的长度。 - 空间复杂度:
。返回值不计入。
分类题单
- 滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环)
- 二分算法(二分答案/最小化最大值/最大化最小值/第K小)
- 单调栈(基础/矩形面积/贡献法/最小字典序)
- 网格图(DFS/BFS/综合应用)
- 位运算(基础/性质/拆位/试填/恒等式/思维)
- 图论算法(DFS/BFS/拓扑排序/基环树/最短路/最小生成树/网络流)
- 动态规划(入门/背包/划分/状态机/区间/状压/数位/数据结构优化/树形/博弈/概率期望)
- 常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)
- 数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)
- 贪心与思维(基本贪心策略/反悔/区间/字典序/数学/思维/脑筋急转弯/构造)
- 链表、树与回溯(前后指针/快慢指针/DFS/BFS/直径/LCA)
- 字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)
欢迎关注 B站@灵茶山艾府