一、 问题描述
小蓝对一个数的数位之和很感兴趣, 今天他要按照数位之和给数排序。当 两个数各个数位之和不同时, 将数位和较小的排在前面, 当数位之和相等时, 将数值小的排在前面。
例如, 2022 排在 409 前面, 因为 2022 的数位之和是 6, 小于 409 的数位 之和 13 。
又如, 6 排在 2022 前面, 因为它们的数位之和相同, 而 6 小于 2022 。
给定正整数 n, m 请问对 1 到 n 采用这种方法排序时, 排在第 m 个的元 素是多少?
输入格式
输入第一行包含一个正整数 n。
第二行包含一个正整数 m 。
输出格式
输出一行包含一个整数, 表示答案。
样例输入
13
5
样例输出
3
样例说明
1 到 13 的排序为: 1,10,2,11,3,12,4,13,5,6,7,8,91,10,2,11,3,12,4,13,5,6,7,8,9 。第 5 个数为 3 。
评测用例规模与约定
对于 30% 的评测用例, 1 <= m <=n <=300
对于 50 %50% 的评测用例, 1≤m≤n≤1000 。
对于所有评测用例, 1≤m≤n≤10^{6} 。
运行限制
-
最大运行时间:3s
-
最大运行内存: 512M
二、问题(运行超时)
package practice;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
// 存储1-n个数
int[] arr1 = new int[n];
// 存储每个数的位数的和
int[] arr2 = new int[n];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = i+1;
arr2[i] = sum(i+1);
}
// 用冒泡法进行排序(从后向前遍历)
for (int i = arr2.length-1; i >0; i--) {
for (int j = 0; j < i; j++) {
if (arr2[j] > arr2[j + 1]) {
int temp1 = arr2[j];
arr2[j] = arr2[j + 1];
arr2[j + 1] = temp1;
int temp2 = arr1[j];
arr1[j] = arr1[j + 1];
arr1[j + 1] = temp2;
}
if (arr2[j] == arr2[j + 1]) {
if (arr1[j] > arr1[j + 1]) {
int temp = arr1[j];
arr1[j] = arr1[j + 1];
arr1[j + 1] = temp;
}
}
}
}
System.out.println(arr1[m-1]);
sc.close();
}
//求各个数位之和
public static int sum ( int n){
int sum = 0;
while (n != 0) {
sum = sum + n % 10;
n = n / 10;
}
return sum;
}
}
运用冒泡排序法运行时间确实长
三、正确代码
看了题解后,Arrays.sort()比较器进行比较
package practice;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
Integer[] arr = new Integer[n + 1];
for (int i = 1; i <= n; i++) {
arr[i] = i;
}
Arrays.sort(arr, 1, n + 1, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
int s1 = sum(o1);
int s2 = sum(o2);
if (s1 > s2) {
return 1;
}
if (s1 < s2) {
return -1;
}
return o1 - o2;//默认升序
}
});
System.out.println(arr[m]);
sc.close();
}
public static int sum(int n) {
int ans = 0;
while (n > 0) {
ans += n % 10;
n /= 10;
}
return ans;
}
}
四、收获
Arrays类对于Comparator比较器的支持
//参数一:被排序的数组,必须是引用类型的元素
//参数二:匿名内部类对象,代表了一个比较器对象
Arrays.sort(arr,new Comparator<Integer>(){
public int compare(Integer o1,Integer o2){
return o1-o2;//默认升序
//return o2-o1;//降序
}
});
```java
Arrays.sort(arr,(Integer o1,Integer o2)->{
return o1-o2;
});