编写一个给出非负整数列表的函数,对它们进行排列,使它们形成尽可能大的数字

时间:2016-03-02 20:40:14

标签: java algorithm sorting collections

我的问题

我有以下规格:

  

编写一个给出非负整数列表的函数,对它们进行排列,使它们形成尽可能大的数字。例如,给定[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);
    }
}

3 个答案:

答案 0 :(得分:3)

基本上,需要以某种方式订购数字以形成最大可能数量。考虑一下这个逻辑:

  • 接受任意2个号码ab
  • 如果ab大于ba,那么a应该在b之前。对?
    • ab ab连接的位置,如果a = 4b = 43ab443且{ {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