最近在写主席树,中间用到了离散化,过来总结一下,c++的有直接的vector然后配合lower_bound函数就可以了,然后java比较麻烦
这下面的两种情况代码转自
https://blog.csdn.net/Viscu/article/details/82631062
https://blog.csdn.net/weixin_42977872/article/details/84592396
第一种:包含重复元素,并且相同元素离散化后也要相同
import java.util.SortedSet;
import java.util.TreeSet;
public class sixth {
public static int lower_bound(int[] arr,int target){ //找到第一个大于等于x的数的位置
int l=0;
int r=arr.length;
while (l<r){
int mid=l+(r-l)/2;
if(arr[mid]>=target){
r=mid;
}else{
l=mid+1;
}
}
return l==arr.length?-1:l; //既然是大于等于 这里其实不太能返回-1啊
}
public static int[] solve(int[] array){
SortedSet<Integer> set=new TreeSet<Integer>();
//利用TreeSet可以同时实现排序和去重 可以代替c++中的unique实现
for(int i=0;i<array.length;++i){
set.add(array[i]);
}
//Integer[] b=(Integer[])set.toArray();
int[] b=new int[set.size()]; //将去重排序的数组赋值给b数组
int ct=0;
for(int cur:set){
b[ct++]=cur;
}
for(int i = 0;i<set.size();i++){
System.out.print(b[i]+" ");
if(i ==set.size()-1 ){
System.out.println();
}
}
for(int i=0;i<array.length;++i){
array[i]=lower_bound(b,array[i])+1; //利用lower_bound找到该数值的排位(rank) 位置是从0开始的,所以这里要加一
System.out.print(array[i]+" ");
//排名代表大小 越前越小 越后越大
}
System.out.println();
//10000000,2,2,123123213离散化成2,1,1,3
return array;
}
public static void main(String[] args) {
int[] a={10000000,2,2,123123213};
int [] d = solve(a);
for(int i = 0;i<4;i++){
System.out.println(d[i]);
}
}
}
第二种:1.包含重复元素,并且相同元素离散化后不相同,2.不包含重复元素,并且不同元素离散化后不同
额,,,,第二种我已经不是第一次写了, ,但是还是倒不过来
public class sixth {
static class Node implements Comparable<Node>{
int rt;
int idx;
public Node(int rt, int idx) {
this.rt = rt;
this.idx = idx;
}
@Override
public int compareTo(Node node) {
return rt-node.rt;
}
}
public static void work(int[] array){
int[] rank=new int[array.length];
Node[] nodes=new Node[array.length];
for(int i=0;i<array.length;++i){
nodes[i]=new Node(array[i],i); //传入数值和坐标
}
java.util.Arrays.sort(nodes); //排序 记得实现Comparable接口 以rt大小排序
for(int i=0;i<array.length;++i){
rank[nodes[i].idx]=i;
}
for(int i=0;i<array.length;++i){
array[i]=rank[i]+1;
}
for(int i = 0;i<array.length;i++){
System.out.println(array[i]);
}
//10000000,2,2,123123213 离散化成 3 1 2 4
}
public static void main(String[] args) {
int[] a={10000000,2,2,123123213};
work(a);
}
}