哈希
unordered_map
:基础概念
- 哈希表容器:
unordered_map
使用哈希函数将键映射到桶中,从而实现高效的键值对存储和查找。 - 键值对存储:每个元素由一个键 (
key
) 和一个值 (value
) 组成,键用于快速访问对应的值。 - 无序:键值对存储在哈希表中,不保证元素的顺序。
- 常用操作复杂度:插入、查找和删除操作的平均时间复杂度为 O(1)O(1)。
1. 类型声明 unordered_map<int, int>
:
- 键类型 (
int
):键是一个整数类型。 - 值类型 (
int
):值也是一个整数类型。
2. 如何理解 unordered_map<int, int> hashmap;
- 类型声明:声明了一个名为
hashmap
的unordered_map
对象,键和值均为整型 (int
)。 - 默认初始化:此对象在创建时,内部无任何键值对。
3. 常用操作
以下是对 unordered_map
的常见操作及示例:
1. 插入元素
cppCopy codehashmap[1] = 10; // 插入键值对 {1, 10}
hashmap[2] = 20; // 插入键值对 {2, 20}
hashmap.insert({3, 30}); // 另一种插入方式
2. 访问元素
cppCopy codestd::cout << hashmap[1]; // 输出 10
std::cout << hashmap.at(2); // 输出 20
注意:使用
at()
方法时,如果键不存在会抛出异常,而[]
运算符会插入一个默认值。
3. 查找元素
cppCopy codeif (hashmap.find(1) != hashmap.end()) {
std::cout << "Key 1 exists!" << std::endl;
}
4. 删除元素
cpp
Copy code
hashmap.erase(1); // 删除键为 1 的元素
5. 遍历元素
cppCopy codefor (const auto &pair : hashmap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
代码完整示例
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<int, int> hashmap;
// 插入元素
hashmap[1] = 10;
hashmap[2] = 20;
// 遍历元素
for (const auto &pair : hashmap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
// 查找元素
if (hashmap.find(1) != hashmap.end()) {
std::cout << "Key 1 found with value: " << hashmap[1] << std::endl;
}
// 删除元素
hashmap.erase(1);
return 0;
}
运行结果可能为:
yamlCopy code1: 10
2: 20
Key 1 found with value: 10
unordered_set
的特性:基本概念
- 唯一性:
std::unordered_set
中的所有元素都是唯一的,重复插入相同的元素会被忽略。
- 无序存储:
- 元素存储顺序不固定,具体顺序由哈希函数决定。
- 高效操作:
- 插入、查找和删除的平均时间复杂度为 O(1)O(1)。
- 最差情况下(哈希冲突严重),复杂度可能退化为 O(N)O(N)。
- 底层实现:
- 使用哈希表(Hash Table)存储数据,通过哈希函数对元素进行分布和管理。
- 键值即元素:
std::unordered_set
的每个元素本身既是键,也是值。
1.语法:
cppCopy code#include <unordered_set>
std::unordered_set<T> set_name;
T
:元素类型。- 默认构造函数:创建一个空集合。
2. 常见操作
操作 | 函数或方法 | 说明 |
---|---|---|
插入元素 | insert(value) | 将 value 插入集合,如果 value 已存在,则插入失败。 |
查找元素 | find(value) | 返回迭代器,指向 value 所在的位置;如果找不到,返回 end() 。 |
删除元素 | erase(value) | 删除值为 value 的元素,如果不存在,则不执行任何操作。 |
获取大小 | size() | 返回集合中元素的数量。 |
清空集合 | clear() | 删除集合中所有元素。 |
检查是否存在 | count(value) 或 find(value) | 判断 value 是否存在,返回布尔值(count 返回 0 或 1)。 |
遍历集合 | 使用范围循环或迭代器 | 遍历集合中所有元素。 |
桶操作 | bucket_count() , bucket_size() | 查看哈希表的桶数量或某个桶中元素的数量,用于观察哈希分布情况。 |
3. 示例代码
#include <iostream>
#include <unordered_set>
int main() {
// 创建 unordered_set
std::unordered_set<int> mySet;
// 插入元素
mySet.insert(10);
mySet.insert(20);
mySet.insert(10); // 重复元素不会插入
// 查找元素
if (mySet.find(10) != mySet.end()) {
std::cout << "10 exists in the set." << std::endl;
}
// 遍历元素
std::cout << "Set elements: ";
for (const int &val : mySet) {
std::cout << val << " ";
}
std::cout << std::endl;
// 删除元素
mySet.erase(20);
// 检查集合大小
std::cout << "Set size after deletion: " << mySet.size() << std::endl;
return 0;
}
输出:
arduinoCopy code10 exists in the set.
Set elements: 10 20
Set size after deletion: 1
4. 使用场景
std::unordered_set
适用于以下场景:
- 快速查找
- 判断某个值是否存在,如单词检查、集合操作等。
- 去重
- 只存储唯一值,例如移除重复数据。
- 高效处理大数据
- 在需要快速插入和查找的场景下表现优越。
Leetcode
1. 两数之和
- 使用哈希表存储每一个元素
- 运用逆向思维 , int x = target - nums[i] , 找到匹配值
49. 字母异位词分组
128. 最长连续序列
- 注意是连续数值
- 只需要枚举每一段的开头
- 除了不是开头端点, 其他的点要从哈希表中删除