Java 特定规则排序-LeetCode 179 Largest Number

Given a list of non negative integers, arrange them such that they form the largest number.

For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.

Note: The result may be very large, so you need to return a string instead of an integer.

题意:

给出无序数组A,利用数组A中的数字进行排列得出一个数字N,使得N最大

分析:

该题归根结底是按照一种特殊的规则对原数组进行排序,使得排序后的数组拼接在一起得到的数字最大。

而这个规则便是:数字按照字典序排序比如321和4,那么321<4,因为从高位开始3<4(ascii码)

但是有一种特殊情况,如30和3,按照字典序排序应该是30>3,但是在本题目中如果我们想组成最大数字必须是30<3,因为303<330

这样我们就得出了排序的规则,那么如何实现这两种规则

解法1

给出整数o1和o2,我们知道字符串之间的比较就是按照字典序进行的,那么我们比较o1+o2和o2+o1即可完成上述规则

代码如下:

 1 public String largestNumber(int[] nums) {
 2         PriorityQueue<String> pq = new PriorityQueue<>(10,
 3                 new Comparator<String>() {
 4                     @Override
 5                     public int compare(String o1, String o2) {
 6                         return (o1 + o2).compareTo(o2 + o1);
 7                     }
 8                 });
 9         for (int i = 0; i < nums.length; i++) {
10             pq.add(Integer.toString(nums[i]));
11         }
12         StringBuilder sb = new StringBuilder();
13         while (!pq.isEmpty()) {
14             sb.insert(0, pq.poll());
15         }
16         String tmp = sb.toString();
17         if (tmp.charAt(0) == '0')
18             return "0";
19         return sb.toString();
20     }

这里我用的是优先队列(即二叉堆,直接用排序也可以)

解法2

这是与实验室师弟讨论的结果,由于在这次排序中无论数字有几位,如果每一位上全是9那么这个数字一定是最大的,必须排在最前面,如{99, 30, 9, 5}那么99和9一定是放在最前面的,那么换个思路,我比较两个数字大小那么可以比较在对应最大的数字所占的百分比。如3和30,那么我比较3/9和30/99的大小来判断30和3的大小

代码如下:

 1 public String largestNumber2(int[] nums) {
 2         PriorityQueue<Integer> pq = new PriorityQueue<>(10,
 3                 new Comparator<Integer>() {
 4                     @Override
 5                     public int compare(Integer o1, Integer o2) {
 6                         int t1 = o1, t2 = o2;
 7                         double a1 = 0.0, a2 = 0.0;
 8                         do {
 9                             a1 = a1 * 10 + 9;
10                             t1 /= 10;
11                         } while (t1 != 0);
12                         do {
13                             a2 = a2 * 10 + 9;
14                             t2 /= 10;
15                         } while (t2 != 0);
16                         if (o1 / a1 > o2 / a2)
17                             return 1;
18                         else if (o1 / a1 < o2 / a2)
19                             return -1;
20                         else
21                             return 0;
22                     }
23                 });
24         for (int i = 0; i < nums.length; i++) {
25             pq.add(nums[i]);
26         }
27         StringBuilder sb = new StringBuilder();
28         while (!pq.isEmpty()) {
29             sb.insert(0, pq.poll());
30         }
31         String tmp = sb.toString();
32         if (tmp.charAt(0) == '0')
33             return "0";
34         return sb.toString();
35     }

注意特殊情况处理就是数组中给出的全是0,而题目要求返回字符串,注意别返回"000"这种情况,特殊处理下。

我看了下Discuss差不多就这两种,大同小异

原文地址:https://www.cnblogs.com/xlturing/p/4473551.html