离散化算法思想及相关题目

1.什么是离散化?

  这是一种处理数据的算法,是使用有序数组中数的下标来映射数,使得一个较小的数可以代指一个叫大的数,常用于当问题给出的数据数据范围特别大,容易导致数组过大不好存储以及引起超时的问题,但同时给出数据的量却又不大时,便可以使用离散化算法来处理数据。

2.离散化算法的一个常用模板?

  在这里我将给出一个离散化算法的常用模板,事实上还有很多模板,但它们的思想是相同的,可以选择自己喜欢的模板来使用。

#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N = 1e5 + 10;//随便给了一个数据范围
//a[i]来记录所有数据
int a[i];
//离散化相关的数组和变量
int pos;//记录离散化数组中有多少值
int disc[N];//离散化数组
unordered_map<int,int> id;//用一个哈希表存储离散化前和后的数据的对应关系
int main()
{
    //输入一组值,个数为n
    int n = 0; cin >> n;
    for(int i = 1;i <= n;i++)
    {
        cin >> a[i];
        disc[++pos] = a[i];
    }
    //离散化
    //先排序
    sort(disc + 1,disc + pos + 1);
    int cnt = 0;//用来记录离散化数组中不重复的数的个数
    for(int i = 1;i <= pos;i++)
    {
        int x = disc[i];
        if(id.count(x)) continue;
        id[x] = ++cnt;
    }
    //处理输出
    for(int i = 1;i <= n;i++) cout << id[a[i]] << " ";

3.两道例题,由于主要都是模板的使用,这里只分析算法思想

  例一:

数据范围:10≤N≤10000000,1≤M≤1000,1≤Ai​≤Bi​≤10000000

  在看到本题目时,首先可以进行模拟,给出Ai,Bi时,便可以遍历数组中的对应部分,修改数组中的值即可,但麻烦的是,数据范围中Ai,Bi严重超出了数组的范围,遍历时一定会造成超时,此时我们就对本题中的数据做离散化处理,需要注意的是,由于离散化处理之后有的A,B范围会被压缩,导致原本不会被覆盖的部分被覆盖,造成答案错误,所以每有一个数字需要进行离散化,我们将比它大1的数字也进行离散化,这样就可以避免上面这种问题的发生。

例二:

数据范围:1≤n≤2×10^4,−2^31≤a<b<2^31

  看到本题时,首先想到的算法是利用差分数组对时间复杂度进行优化,但由于数据范围过大,数组不够开,所以我们要先对数据做离散化处理再进行差分算法的使用,需要注意的是,本题在最后部分需要用一个数组的下标来找回原来的数字是多少,所以我们要修改一下离散化模板,我们要在排序之后进行一下去重处理,调用一下unique函数,它的参数和sort是一样的,这样就可以处理掉这个问题。

4.结语:

这就是离散化算法的全部内容了,欢迎各位于晏、亦菲和我一起交流学习。

5.注意:

  在上面两道题目的解释中,我们可以发现,其实直接使用离散化算法是经常会引起错误情况出现的,所以在使用模板时,我们要多加考虑,这样才能避免错误。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值