一.map详解
C++STL容器类(vector、list、map、set、deque)之一
map<key,value>
- 第一个可以称为关键字(key),每个关键字只能在map中出现一次;
- 第二个可能称为该关键字的值(value);
- key or value 都可以是任何类型,无论是int、float、结构体、类
基本操作函数
begin() 返回map头部
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
二.例题:复杂链表的复制
请实现 copyRandomList
函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next
指针指向下一个节点,还有一个 random
指针指向链表中的任意节点或者 null
。
示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]] 输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
初步思路:
1.若是普通链表,直接循环创建即可。
2.由于random指针指向的节点完全随机,且是否创建为未知数。
3.将会导致,想要创建节点A就先需要创建节点A的random指针指向的节点B,而要创建节点B就先需要创建节点B的random指针指向的节点C,以此构成无限需求链。但是这也启发我们使用递归的思想来创建节点。
具体思路:
1.递归函数读入需要创建的节点
2.判断节点是否已经创建:
(1)若尚未创建:
①new一个新节点,对value初始化
②递归调用函数本身,新参数为需创建节点->next
②递归调用函数本身,新参数为需创建节点->random
(2)若已经创建:返回已经创建的节点
3.返回新创建的节点
要点:
如何判断一个节点是否已经创建?
想法1:构建标记数组,用数字来标记节点是否已经被创建
想法1的问题:节点是链表,没有下标,节点的值也许会重复,无法使用节点值来构成下标。
想法2:通过想法1,就能自然想到使用map。
代码示例:使用函数为copyRandomList(Node* head)
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
unordered_map<Node*, Node*> List;
Node* copyRandomList(Node* head) {
if(head==nullptr) return nullptr;
if(!List.count(head)){
Node* temp = new Node(head->val);
List[head] = temp;
temp->next = copyRandomList(head->next);
temp->random = copyRandomList(head->random);
}
return List[head];
}
};