【问题标题】:Write a function that given a list of non negative integers, arranges them such that they form the largest possible number编写一个给定非负整数列表的函数,将它们排列成可能的最大数
【发布时间】:2016-06-15 22:04:55
【问题描述】:

我的问题

我有以下规格:

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

【问题讨论】:

  • 你不能按字母倒序加入他们吗?是在作业中实现排序算法的一部分,还是您可以为该部分使用库函数并且只需要弄清楚如何应用它?
  • @tobias_k 不适用于具有不同位数的数字。即 10, 9 比 910 大
  • 使用 Collections.sort() 我正在对每个地图中的列表进行排序。
  • @JimGarrison 哎呀,你是对的。一定是不小心颠倒了排序。但这仍然行不通。考虑数字4, 45;这里45 应该在4 之前;但是对于4, 434 应该排在第一位。
  • 我对这个问题投了反对票,原因如下:(1)它询问如何提高空间和时间复杂度的“建议”,而不解释当前的复杂度是什么或需要什么, (2) 核心问题实际上是“我的代码有错误,请更正代码”,这是一个糟糕问题的典型例子。详细的错误是什么?

标签: java algorithm sorting collections


【解决方案1】:

基本上,数字需要以某种方式排序以形成最大可能的数字。考虑这个逻辑:

  • 取任意两个数字ab
  • 如果ab 大于ba,那么a 应该在b 之前。正确的?
    • 其中abab 连接,所以如果a = 4b = 43 那么ab443ba434

您可以在自定义比较器中实现此功能,并将其传递给Collections.sort,如下所示:

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);
}

这是使用 Java 8 的基本相同代码:(感谢@marcospereira!)

public String maxNumber(Integer ... numbers) {
    return Stream.of(numbers)
            .filter(n -> n >= 0)
            .map(Object::toString)
            .sorted((s1, s2) -> (s2 + s1).compareTo(s1 + s2))
            .collect(Collectors.joining());
}

【讨论】:

  • 完成。我还添加了一个过滤器来避免负数。
  • @marcospereira 哦,太漂亮了,谢谢! (添加学分)
【解决方案2】:

无论你如何组合这些数字,它们都会产生一个具有相同位数的数字。这意味着您要对它们进行排序以将最大的数字放在首位。实际上,这与在字符串中对数字进行排序的问题相反,因为您想像对字符串一样对数字进行排序(从第一个数字开始)

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

【讨论】:

  • 不确定。对于int[] a = {9, 90};,它会打印909,但它应该打印990。我认为我们需要类似基数排序的效果。
  • @KedarMhaswade,这就是 Janos 在这方面有正确想法的原因。谢谢。
【解决方案3】:

这是在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}"`);
  }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多