思路来源于一个算法题。有点懒就不怎么改动代码啦。可根据需要自行改动。
给定序列 (a1, a2, · · · , an) = (1, 2, · · · , n),即 ai = i。
小蓝将对这个序列进行 m 次操作,每次可能是将 a1, a2, · · · , aqi 降序排列,或者将 aqi , aqi+1, · · · , an 升序排列。
请求出操作完成后的序列。
以下代码可用于对数组的指定位置区间进行升序或者降序。
主函数
n:表示要排序的元素,如n=3,数组元素就是1,2,3
m:表示要执行升序或降序的次数。
pi:为0降序,为1升序。
qi:参数。
样例:
输入:
3 3
0 3
1 2
0 2
输出:
3 1 2
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n=sc.nextInt(),m=sc.nextInt();
int[] a=new int[n];
for(int i=0;i<n;i++){
a[i]=i+1;
}
while(m>0){
m--;
int pi=sc.nextInt(),qi=sc.nextInt();
if(pi==0){
des(a,0,qi-1);
}else{
asc(a,qi-1,n-1);
}
}
for(int kk:a){
System.out.print(kk+" ");
}
}
降序
public static void des(int array[],int begin,int end){
int max = Integer.MIN_VALUE;
for(int i=begin;i<=end;i++){
if (array[i] > max){ //找到最大值
max = array[i] ;
}
}
int[] hashArray = new int[max + 1]; //定义哈希数组
for (int i = 0; i < hashArray.length; ++i){
hashArray[i] = 0; //为哈希数组赋初值0,舍去这步也可,默认初始0.
}
for(int i=begin;i<=end;i++){
++hashArray[array[i]];
}
int index = begin;
for (int i = hashArray.length-1; i >=0; i--){
for (int j = 0; j < hashArray[i]; ++j){
array[index++] = i;
}
}
}
升序
public static void asc(int array[],int begin,int end){
int max = Integer.MIN_VALUE;
for(int i=begin;i<=end;i++){
if (array[i] > max){
max = array[i] ;
}
}
int[] hashArray = new int[max + 1];
for (int i = 0; i < hashArray.length; ++i){
hashArray[i] = 0;
}
for(int i=begin;i<=end;i++){
++hashArray[array[i]];
}
int index = begin;
for (int i = 0; i <hashArray.length; i++){
for (int j = 0; j < hashArray[i]; ++j){
array[index++] = i;
}
}
}
番外
除了利用哈希的思想实现排序。我们经常想到的Arrays.sort(数组名,初始位置,结束位置),它的时间复杂度应该跟版本有关,不同版本时间复杂度不同。有的用的快速排序,有的是快速排序(平均时间复杂度和最坏时间复杂度分别是O(nlgn)、O(n^2))和插入排序相结合,不甚了解,感谢包容!
当然,在上面的升序代码中我们可以使用Arrays.sort(a,begin,end),时间复杂度应该相差不大!
重在理解降序!以便在苦思算法的时间复杂度中可以有机会往这一方面跑!