题目
问题描述
离散化就是把无限空间(或非常大的空间)中有限的个体映射到有限的空间(较小空间)中去,以此提高算法的时空效率。通俗的说,离散化就是在不改变数据相对大小的条件下,对数据进行相应的缩小。
####栗子
原始数据:
1 | 8 999 91 100000 0000 15 999 91 |
离散化后:
1 | 1 3 4 2 3 |
离散化有什么用处呢?有时候我们需要根据数值的大小开一个数组,由于数值很多,没办法开那么大的数组(大了会超内存限制的),但是数据的个数有限。
如:有500000个数字,他们的范围是0-2000000000,这样就满足离散化的条件。我们可以把这些数离散化,最小的缩小为1,大小相邻的依次增加1,这样所有的数的范围一定能缩小到1到500000之间,同时不改变相对大小关系。
####任务
给你n个整数序列a[1],a[2],..,a[n]。请你在不改变相对大小关系的前提下进行离散化。
####要求
1.离散化后,最小的数值为1。
2.原序列中相同的数,离散后还应相同。
3.大小相邻的两个数离散后相差为1。
4.离散后序列相对位置不变。
###输入
第一行n 原始数据的个数 。第二行n 个用一个空格隔开的整数 。
###输出
一行原序列离散后相应的序列 ,相邻两个数之间一个空格隔开。
###输入输出样例
| discretize.in | discretize.out |
|---|---|
| 8 99991 1000000000 15 99991 | 1 3 4 2 3 |
###数据范围
30%的数据: n<100, 0< a[i]<1000;
100% 的数据: n<500000 0< a[i]<2000000000
第一种方法
思路
其实就是用一个辅助的数组把你要离散的所有数据存下来。
然后排序,排序是为了后面的二分。
去重,因为我们要保证相同的元素离散化后数字相同。
再用二分把离散化后的数字放回原数组。
注意事项
1.去重并不是把数组中的元素删去,而是重复的部分元素在数组末尾,去重之后数组的大小要减一
2.二分的时候,注意二分的区间范围,一定是离散化后的区间
3.如果需要多个数组同时离散化,那就把这些数组中的数都用数组存下来
核心代码
1 | //n:原数组大小 |
第二种方法
思路
其实就是排序之后,枚举着放回原数组
用一个结构体存下原数和位置,按照原数排序
我结构体里面写了个重载,也可以写一个比较函数
最后离散化后数在rank[]里面
1 | struct Node |




