离散化
概念讲解
什么是离散化?
将值域大但数量少的数据映射到连续的小值域。
适用场景
- 值域大(如 10^9),但只有 10^5 个数
- 需要用数组下标访问
实现
12345678910vector<int> discretize(vector<int>& a) {
vector<int> sorted = a;
sort(sorted.begin(), sorted.end());
sorted.erase(unique(sorted.begin(), sorted.end()), sorted.end());
return sorted;
}
int getIndex(vector<int>& sorted, int x) {
return lower_bound(sorted.begin(), sorted.end(), x) - sorted.begin();
}考点分析
初赛考查方式
- 程序阅读: 离散化程序
- 编程题: 值域压缩
常见考点
- 离散化实现
- 配合树状数组
- 配合线段树
例题精讲
例题 1:离散化
题目: 将 {100, 500, 1000, 50, 500} 离散化。
解答:
排序去重:{50, 100, 500, 1000}
映射:50→0, 100→1, 500→2, 1000→3
练习题
- 离散化的作用是什么?
查看答案
离散化的作用是将值域大但数量少的数据映射到连续的小值域。
例如:值域 ,但只有 个数,离散化后值域变为 。
这样就可以用数组下标访问,配合树状数组、线段树等数据结构使用。
- 如何实现离散化?
查看答案
离散化的实现:
- 排序:将所有值排序
- 去重:去除重复值
- 映射:用 lower_bound 查找下标
12345vector<int> sorted = a;
sort(sorted.begin(), sorted.end());
sorted.erase(unique(sorted.begin(), sorted.end()), sorted.end());
int index = lower_bound(sorted.begin(), sorted.end(), x) - sorted.begin();- 离散化的时间复杂度是多少?
查看答案
- 排序:
- 去重:
- 单次查找:
总复杂度:
易错点
⚠️ 注意:
- 要先排序再去重
- 用 lower_bound 查找下标
- 下标从 0 还是 1 开始要统一
- 离散化后值域变小