Rời rạc hóa
简介
离散化是一种数据处理的技巧,本质上可以看成是一种 哈希,其保证数据在哈希以后仍然保持原来的 全/偏序 关系.
通俗地讲就是当有些数据因为本身很大或者类型不支持,自身无法作为数组的下标来方便地处理,而影响最终结果的只有元素之间的相对大小关系时,我们可以将原来的数据按照排名来处理问题,即离散化.
用来离散化的可以是大整数、浮点数、字符串等等.
实现
将一个数组离散化,并进行查询是比较常用的应用场景.
方法一
通常原数组中会有重复的元素,一般把相同的元素离散化为相同的数据.
方法如下:
-
创建原数组的副本.
-
将副本中的值从小到大排序.
-
将排序好的副本去重.
-
查找原数组的每一个元素在副本中的位置,位置即为排名,将其作为离散化后的值.
1 2 3 4 5 6 7 8 | |
参考实现中使用的 STL 算法可参考 STL 算法.
同样地,我们也可以对 std::vector 进行离散化:
1 2 3 4 5 6 | |
方法二
根据题目要求,有时候会把相同的元素根据输入顺序离散化为不同的数据.
此时再用 std::lower_bound() 函数实现就有些困难了,需要换一种思路:
-
创建原数组的副本,同时记录每个元素出现的位置.
-
将副本按值从小到大排序,当值相同时,按出现顺序从小到大排序.
-
将离散化后的数字放回原数组.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
复杂度
对于方法一,去重复杂度为 \(O(n)\),排序复杂度为 \(O(n \log n)\),最后的 \(n\) 次查找复杂度为 \(O(n \log n)\).
对于方法二,排序复杂度为 \(O(n \log n)\).
故两种方法的总时间复杂度都为 \(O(n \log n)\).
空间复杂度为 \(O(n)\).
习题
Last updated on this page:, Update history
Found an error? Want to help improve? Edit this page on GitHub!
Contributors to this page:GavinZhengOI, PlanariaIce
All content on this page is provided under the terms of the CC BY-SA 4.0 and SATA license, additional terms may apply