我有以下规格:
编写一个给出非负整数列表的函数,对它们进行排列,使它们形成尽可能大的数字。例如,给定[50,2,1,9],最大形成数为95021。
我已经采取了解决问题的方法,但它失败了。例如,给定输入[90,91,89,999],此代码的结果为[909199989],但应该是[999919089]。
简单来说,它与基数排序相反。
步骤
1)根据值创建桶
2)每个桶都有元素列表
3)对每个桶中的列表进行排序
4)以相反的顺序显示结果。
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Scanner;
public class ReverseMaxPossibleNumber {
public static void main(String[] args) {
int[] a = { 50, 2, 1, 9 };
int len = a.length;
String ch = "";
List<Map<String, ArrayList<String>>> list_map = new ArrayList<Map<String, ArrayList<String>>>();
Map<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
for (int i = 0; i < len; i++) {
ch = "" + a[i];
String str = "";
ArrayList<String> arraylist = new ArrayList<String>();
for (int j = 0; j < len; j++) {
str = "" + a[j];
if (ch.charAt(0) == str.charAt(0)) {
arraylist.add(str);
Collections.sort(arraylist);
map.put("" + ch.charAt(0), arraylist);
}
}
}
list_map.add(map);
String str = "";
for (String key : map.keySet()) {
str = map.get(key) + str;
}
str = str.replaceAll("\\D+", "");
System.out.println(str);
}
}
答案 0 :(得分:3)
基本上,需要以某种方式订购数字以形成最大可能数量。考虑一下这个逻辑:
a
和b
ab
大于ba
,那么a
应该在b
之前。对?
ab
a
和b
连接的位置,如果a = 4
和b = 43
则ab
为443
且{ {1}}是ba
您可以在自定义比较器中实现此功能,并将其传递给434
,如下所示:
Collections.sort
这里使用Java 8的代码基本相同:(感谢@marcospereira!)
public String maxNumber(int[] numbers) {
// convert int[] -> List<String>
List<String> list = new ArrayList<>(numbers.length);
for (int num : numbers) {
list.add(String.valueOf(num));
}
// sort using custom comparator
Collections.sort(list, (o1, o2) -> (o2 + o1).compareTo(o1 + o2));
// join sorted items, forming max possible number
return String.join("", list);
}
答案 1 :(得分:1)
这里是在JS上的实现
https://jsfiddle.net/b6r81jv9/
let input = [
{test: [1, 2, 3, 4, 5, 6, 7, 8], res: "87654321"},
{test: [50, 2, 1, 9], res: "95021"},
{test: [1, 19], res: "191"},
{test: [9, 90], res: "990"},
{test: [9, 90, 900], res: "990900"},
{test: [9, 909, 9909, 999], res: "99999909909"}
];
function big_number_simplified(arr) {
return [...arr].sort((a, b) => b.toString() + a > a.toString() + b ? 1 : -1);
}
input.forEach(item => {
let res_1 = big_number_simplified(item.test).join('');
if (res_1 === item.res) {
console.log(`[${item.test.join(',')}]: "${res_1}"`);
} else {
console.error(`ERROR: [${item.test.join(',')}]: "${res_1}", expected: "${item.res}"`);
}
});
答案 2 :(得分:0)
无论您如何组合数字,他们都会生成一个数字相同的数字。这意味着您要对它们进行排序以将最大数字放在首位。事实上,这是在字符串中对数字进行排序的相反问题,因为你想像对待字符串一样排序数字(从第一个数字开始)
int[] a = {90, 91, 89, 999};
long num = Long.parseLong(
IntStream.of(a)
.mapToObj(Integer::toString)
// reverse sort them as Strings.
.sorted((x, y) -> (y + x).compareTo(x + y))
.collect(Collectors.joining()));
System.out.println(num);
打印
999919089