知识点
题目来源:https://leetcode-cn.com/problems/copy-list-with-random-pointer/
- 结构体使用
- 链表创建
- 递归算法
- 引用传参
- 哈希表使用
代码
#include<iostream>
#include<unordered_map>
using namespace std;
struct Node{ // 创建结构体
int val; // 节点值
Node *next, *random; // 节点指针
Node(int x): val(x), next(nullptr), random(nullptr){}; // 节点初始化
};
unordered_map<Node*, Node*> dic; // 创建键值都为Node类型地址的哈希表
Node* copyRandomList(Node* head) { // 克隆指针函数
if (head == nullptr) return nullptr; // 递归返回条件1,节点不存在则返回nullptr
if (dic.count(head)) return dic[head]; // 递归返回条件2,节点已在哈希表中,则返回对应值
Node* root = new Node(head->val); // 节点不在哈希表,说明克隆节点还未创建,则创建之
dic[head] = root; // 建立原节点和克隆节点对应关系
// cout << "R0-" << head->val << ' ';
root->next = copyRandomList(head->next); // 第一次递归,连接链表
// cout << "R1-" << head->val << ' ';
root->random = copyRandomList(head->random);// 第二次递归,将随机指针连接上
return root; // 返回节点
// 程序运行过程,第一次递归会完成所有克隆节点创建并放入哈希表,第二次递归连接上即可
// 取消两个cout的注释,得到的输出是:
// R1-0 R1-1 R1-2 R1-3 R1-4 R2-4 R2-3 R2-2 R2-1 R2-0
// 前面5个是节点创建顺序,后面5个是random指针的连接顺序(此时节点已全部创建完毕)
}
int main(){
int arr[] = {3,1,4,0,2};
Node head(0);
unordered_map<int,Node*>mp; /
Node *p1 = &head;
mp[0] = &head;
for (int i=1; i<5; ++i){
p1->next = new Node(i);
p1 = p1->next;
mp[i] = p1;
}
p1 = &head;
for (int i=0; i<5; ++i){
p1->random = mp[arr[i]];
p1 = p1->next;
}
Node *clone = copyRandomList(&head);
return 0;
}
后记
- 结构体的关键字是struct,其语法结构与class基本相同,主要区别在于结构体默认成员变量和函数都是public,而class默认的成员变量和函数是private(类外不可调用)
- 哈希表的键值可以是指针指向的地址,例如
unordered_map<int*, int*> dic
- 递归算法可以代替使用循环,提高程序的可读性,但并不提高效率