「数组」离散化 / Luogu B3694(C++)

目录

概述

思路

算法过程

复杂度

Code


概述

Luogu B3694:

给定一个长度为 n 的数列 aa。定义 rank(i) 表示数列 a 中比 ai 小的不同数字个数再加一。

对 1≤i≤n,现在请你求出所有的 rank(i)。

输出格式

对每组数据,输出一行 n 个整数,用空格隔开,依次示 rank(1)到 rank(n)。

我们来讲一个十分常用的小算法:离散化。

离散化并不单独作为一个算法出现,而是常作为一个预处理步骤。

所谓离散化,就是使用数组元素的相对排名替代原始数组元素。

例如,

cpp 复制代码
     i  0 1 2 3 4
nums[i] 9 7 4 0 1000
         ↓
nums[i] 4 3 2 1 5

这样我们在保证元素的相对关系的前提下,使得元素的分散程度减小了。

换句话说,如果元素分布范围很大,或者元素是浮点数以及其他类型,在不关注元素的绝对性质时,用离散化处理会使得我们关注的范围更加紧凑。

离散化在许多只关注元素相对性质的算法里有广泛的应用。

思路

一共有三个数组:原始数组,排序后的原数组,离散化数组。

先复制一份原始数组,对其进行排序,这样(元素下标-数组头指针)就得到了元素在原数组的排名。

原始数组遍历,对于第i个元素,它在排序后数组中处于pos位置,则离散化数组[i]=pos。

需要注意的是:在考虑重复元素的只占排名时,我们要对排序后数组进行去重。

算法过程

使用C++STL算法库:

sort()排序数组。

unqiue()对排序后数组去重。

lower_bound()利用二分查找找到排序后数组中元素的位置。

排序数组b,

cpp 复制代码
sort(b,b+n);

排序后对数组去重,得到排序后去重数组b[i],

cpp 复制代码
int* end=unique(b,b+n); 

unqiue会将数组中的重复元素转移至数组末位,返回去重后数组无重复区的后一个位置。

二分查找得到a[i]在b中的位置,减去b得到相对排名,

cpp 复制代码
for(int i=0;i<n;i++)
        cout<<lower_bound(b,end,a[i])-b+1<<' ';

对于本题,直接输出离散结果即可,另外,题目要求的排序从1开始。

对于二分查找lower_bound的内部实现:「数组」二分查找模版|二段性分析|恢复二段性 / LeetCode 35|33|81(C++)

对于数组去重unqiue的内部实现:

「数组」数组双指针算法合集:二路合并|逆向合并|快慢去重|对撞指针 / LeetCode 88|26|11(C++)

复杂度

时间复杂度:O(nlogn)

空间复杂度:O(n)

Code

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
void solve(){
    int n;cin>>n;
    int a[n],b[n];
    for(int i=0;i<n;i++){
        cin>>a[i];
        b[i]=a[i];
    }
    sort(b,b+n);
    int* end=unique(b,b+n);
    for(int i=0;i<n;i++)
        cout<<lower_bound(b,end,a[i])-b+1<<' ';
    cout<<endl;
}
int main(){
    int t;cin>>t;
    while(t--)solve();
}
相关推荐
岁岁岁平安1 分钟前
Java基础(Arrays工具类)(asList()方法)(详细)
java·开发语言·集合·arrays·aslist
暴怒香菜统治世界5 分钟前
c语言--结构体
c语言·开发语言·数据结构·笔记·算法
kuilaurence6 分钟前
C语言中的输入控制重要基础
c语言·开发语言
九离十7 分钟前
C语言初识(一)
c语言·开发语言
coffee_baby14 分钟前
《解锁高效流程设计:深度剖析责任链模式与实战应用》
java·开发语言·责任链模式
予早15 分钟前
LeetCode 427. 建立四叉树
算法·leetcode
流星白龙19 分钟前
【C++算法】4.双指针_快乐数
c++·算法
晴子呀20 分钟前
一个有趣的编程题实战----交替打印线程
java·开发语言
EterNity_TiMe_23 分钟前
【Linux基础IO】深入解析Linux基础IO缓冲区机制:提升文件操作效率的关键
linux·运维·服务器·开发语言·学习·性能优化·学习方法
羑悻的小杀马特23 分钟前
AVL树(平衡二叉树)的介绍以及相关构建
c++·算法·平衡二叉树·avl树