数列离散化
题目解析
这段 C++ 代码解决的问题主要是对一系列整数进行离散化。离散化是一种常见的数据预处理方法,常用于处理具有明显区间特性的数据。离散化可以压缩数据的值域,使得处理更为便捷。
在这个问题中,给定一个整数数组,我们需要将数组中的所有数值离散化到从
解题思路
- 读取并处理每个测试用例:对于每个测试用例,首先读入数组的长度
n ,然后读入n 个整数,存储到数组a 中。同时,将数组a 的内容复制到数组b 中。while(t--) { int n; cin >> n; vector<int> a(n), b(n); for(int i = 0;i < n;i++) cin >> a[i],b[i] = a[i]; ... - 排序并去重:对数组
b 进行排序,然后删除重复元素。这一步是离散化的关键步骤,它将所有不同的数值按照大小顺序排列。sort(b.begin(),b.end()); b.erase(unique(b.begin(), b.end()),b.end()); - 进行离散化:遍历数组
a ,使用 lower_bound 函数找到每个元素在数组b中的位置(由于数组b是排序过的,因此位置就相当于排名),然后将这个位置作为新的编号。由于数组下标从0 开始,所以需要加1 。for(int i = 0;i < n;i++) { a[i] = lower_bound(b.begin(),b.end(),a[i])-b.begin()+1; cout << a[i] << " "; }在这个过程中,主要使用到了排序、二分查找和去重这几个算法。其中,sort 函数用于排序,unique 函数用于去重,lower_bound 函数用于二分查找。
这个代码的时间复杂度主要取决于排序和二分查找的复杂度,分别为
AC 代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
vector<int> a(n), b(n);
//复制到两个数组
for(int i = 0;i < n;i++) cin >> a[i], b[i] = a[i];
sort(b.begin(), b.end()); //对b数组排序
b.erase(unique(b.begin(), b.end()), b.end()); //移除b中的重复元素
//离散化处理:对a中的每个元素,查找其在b中的排序位置,并输出
//这样可以将任何一组数据映射到一组连续的整数上,方便后续处理
for(int i = 0;i < n;i++)
{
a[i] = lower_bound(b.begin(),b.end(),a[i])-b.begin()+1;
cout << a[i] << " ";
}
cout << endl;
}
return 0;
}