题目描述
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路
思路1:求数组中所有数字的全排列,类似于“字符串的排列”,然后把每个排列拼起来,求最小值。 (时间复杂度很高,n个数字有n!个排列)
思路2:自定义排序规则。本题核心 -> 「如何对字符串数组进行排序」
- 对于数字m和n,可以拼接成mn和nm,如果mn<nm,我们定义m小于n。反之则相反。利用这个排序规则,从小排到大即可实现题目要求。
- 拼接m和n时,要考虑到大数问题,因此将m和n拼接起来的数字转换成字符串处理。因为mn和nm的字符串位数相同,因此它们的大小只需要按照字符串大小的比较规则就可以了。
- 具体实现:重写compare(Object o1, Object o2)方法来规定比较规则。
解法1(利用Arrays.sort())
import java.util.*; public class Solution { // 利用Arrays.sort()排序 //运行时间:135ms 占用内存:14720k public String PrintMinNumber(int [] numbers) { if (numbers == null || numbers.length <= 0) return ""; //Step01 int类型数组转化为 String类型的数组 String[] arr = new String[numbers.length]; for (int i = 0; i < numbers.length; i++) { arr[i] = String.valueOf(numbers[i]); //arr[i] = numbers[i] + ""; // 与String相加 也可以把int转化为String } //Step02关键: 对String类型数组排序 // 使用lamda表达式Arrays.sort(arr, (参数列表) -> {返回语句}); Arrays.sort(arr, (o1, o2) -> { return (o1 + o2).compareTo(o2 + o1); //升序 两个字符串拼接,把拼接的结果较小的排到前面 }); // Arrays.sort(arr, new Comparator<String>() { // @Override // public int compare(String o1, String o2) { // return (o1 + o2).compareTo(o2 + o1); //升序 两个字符串拼接,把拼接的结果较小的排到前面 // } // }); //Step3 String[]数组 转化为 String类型 StringBuilder sb = new StringBuilder(); for (String s : arr){ sb.append(s); } return sb.toString(); } }
解法2(利用list.sort() 或 Collections.sort())
import java.util.*; public class Solution { // 利用list.sort() 或 Collections.sort() // list.sort() 运行时间:93ms 占用内存:15188k // Collections.sort() 运行时间:87ms 占用内存:15148k public String PrintMinNumber(int [] numbers) { if (numbers == null || numbers.length <= 0) return ""; ArrayList<String> list = new ArrayList<>(); for (int num : numbers) list.add(String.valueOf(num)); // Collections.sort(list,(o1, o2) -> { // return (o1+o2).compareTo(o2+o1); // }); list.sort((o1, o2) -> { return (o1+o2).compareTo(o2+o1); }); StringBuilder sb = new StringBuilder(); for (String s : list) sb.append(s); return sb.toString(); } }
收获
(1)如果把两个int型的整数拼接起来得到的数字可能会超过int型数字能表达的范围,导致数字溢出。 解决方案是「用字符串表示数字」,这样就能简捷得解决大数问题了~
(2)会区分Comparable、CompareTo()、Comparator和compare()
- Comparable是一个接口,其中可以重写CompareTo()方法;
- Comparator是一个比较器类:可以重写其中compare(Object o1, Object o2)方法;Comparator对象可以被传入Arrays.sort()、PriorityQueue()中
参考: