题目链接

题目描述

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

示例

  1. 输入:
  2. [3,32,321]
  3. 输出:
  4. "321323"

解题思路

可以看成是一个排序问题,在比较两个 字符串 S1 和 S2 的大小时,应该比较的是 S1+S2 S2+S1 的大小,如果 S1+S2 < S2+S1 ,那么应该把 S1 排在前面,否则应该把 S2 排在前面。

要准确看到最后输出的是 「字符串」 ,所以要想到将原int数组,变为字符串数组,然后通过字符串相加,得到的新字符串去比较大小,得到最终结果

注意:

  1. 最后输出是字符串格式
  2. 通过S1+S2S2+S1去进行排序

精华:

  1. 看到最后输出的是字符串
  2. 将int数组变为字符串数组
  3. 因为是字符串,所以比较s1+s2和s2+s1的大小
  4. 排序
  5. 字符串连接
  6. 输出

代码

  1. public String PrintMinNumber(int[] numbers) {
  2. if (numbers == null || numbers.length == 0){
  3. return "";
  4. }
  5. int n = numbers.length;
  6. String[] nums = new String[n];
  7. for (int i = 0; i < n; i++) {
  8. nums[i] = numbers[i] + "";
  9. }
  10. Arrays.sort(nums, (s1, s2) -> (s1 + s2).compareTo(s2 + s1));
  11. String ret = "";
  12. for (String str : nums) {
  13. ret += str;
  14. }
  15. // StringJoiner joiner = new StringJoiner("");
  16. // 数组不能使用lambda表达式
  17. // nums.forEach(joiner::add);
  18. // 若想使用,可以将数组转换为list
  19. // Arrays.asList(nums).forEach(joiner::add);
  20. return ret;
  21. }
  1. public String PrintMinNumber(int[] numbers) {
  2. List<String> nums = new ArrayList<>();
  3. for (int number : numbers) {
  4. nums.add(String.valueOf(number));
  5. }
  6. nums.sort(Comparator.comparing(s -> s, (o1, o2) -> (o1 + o2).compareTo(o2 + o1)));
  7. StringJoiner joiner = new StringJoiner("");
  8. nums.forEach(joiner::add);
  9. return joiner.toString();
  10. }

代码分析



  • java8 lambda表达式(这块内容写完后,再补连接)

  • 只有函数式接口才可以用java8 特性 lambda 表达式
    1. @FunctionalInterface
    2. public interface Comparator<T> {......}
    @FunctionalInterface 修饰的接口,叫做函数式接口

  • Arrays 不能使用 lambda表达式 输出
    要使用lambda 表达式,需要将数组变为 ArrayList
    Arrays.asList(array).forEach(System.out::println);

Arrays.asList(array).forEach(joiner::add);


  • String.valueOf() 将括号内的数据转换成 String 类型

  • 不能定义成 StringBuilderStringBuilder 是一个可变字符串不是字符串数组。

把握住核心

  • 将int数组转换为字符数组
  • 字符数组之间进行相加排序。 s1+s2s2+s1