不一样的排序
- 描述:现在有 n 个数,需要用因子个数的多少进行排序,因子个数多的排在后面,因子个数少的排在前面,如果因子个数相同那么就比较这个数的大小,数大的放在后面,数小的放在前面。现在让你说出排序之后第 K 个位置的数字是多少。
- 输入:
第 1 个整数为整数 K,1 ≤K ≤ 10^6 ;
第 2 个为整数 n,表示数字的数量,n<10^7;
接下来有 n 个整数,每个数的大小不超过 10^6 。 - 输出:输出排序之后的第 K 位置的数值。
- 输入样例:4 6 1 2 3 4 5 6; 1 2 3 4 5 6按因子个数排序后是:1 2 3 5 4 6
- 输出样例:5
- 难度:☆☆两颗星
这道题双列集合TreeMap<>,因为该集合的构造函数中可以自定义比较器Comparator,根据自定义比较器确定元素的排序。首先,需要自定义一个函数计算每个数字的因子个数,然后将数字作为Key,因子个数作为Value存入集合中,根据自定义的比较器,元素的排序是按照题中规则进行排序的。因此,只要找出集合中第K个元素的Key,并将其输出。整个程序运行时间稍微的有点长花了2.07 s。ps:我也很无奈,回头再改进,试试stream流和函数式接口来操作。
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
String line;
while (scan.hasNextLine()) {
line = scan.nextLine().trim();
String[] arr = line.split(" ");
int[] intArr = new int[arr.length-2];
TreeMap<Integer, Integer> tm = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer key1, Integer key2) {
return count(key1) - count(key2) == 0 ? key1 - key2 :count(key1) - count(key2);
}
});
for (int i = 0; i < arr.length -2; i++) {
intArr[i] = Integer.parseInt(arr[i+2]);
tm.put(intArr[i], count(intArr[i]));
}
int pos = Integer.parseInt(arr[0]) - 1;
int cnt = 0;
for (Integer key : tm.keySet()) {
if(cnt == pos) {
System.out.println(key);
return;
}
cnt++;
}
}
}
public static int count(int n){
int s = 1;
for(int i = 2; i * i <= n; i++){
if(n % i == 0){
int a = 0;
while(n % i == 0){
n /= i;
a++;
}
s = s * (a + 1);
}
}
if(n > 1) s = s * 2;
return s;
}
}