剑指Offer:把数组排成最小的数

xiaoxiao2021-02-28  64

输入一个正整数数组,把数组里所有数字拼接起来排成一个数, 打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321} ,则打印出这 3 个数字能排成的最小数字 321323.       最直接的方法就是求出这个数组的全排列,解法在剑指Offer:字符串的排列中详细介绍了,将全排列组成一个数字,再比较每个数字,得出最小值。n个数字有n!种排列方式,效率不高。并且我们要考虑全排列组成的数字也许超过int类型的范围了,这是个隐形的大数问题,我们应该使用字符串解决。

      其实这道题目本质上是要求我们找出一种排序规则确定数组中的数字哪些在前,哪些在后,简单的字符串比较已经是不符合要求的了。

      解决这一问题的思路是相加比较。具体如下:我们有两个字符m和n,要确定m在前还是n在前我们m+n(记为mn)和n+m(记为nm)得到两个字符串。如果mn<nm,说明m<n,m应该在前;否则,n在前。

实现代码:

private static String PrintMinNumber(int[] array){ if(array==null){ throw new RuntimeException("Array is null!error"); } if(array.length==0){ throw new RuntimeException("Array'len is zero!"); } String[] strs = new String[array.length]; for (int i=0;i<array.length;i++) { strs[i] = String.valueOf(array[i]); } QuickSort(strs,0,strs.length-1); String MinStr = ""; for (String str : strs) { MinStr += str; } return MinStr; } public static void QuickSort(String strs[],int left,int right){ if(left<right){ int parPos = Partition(strs,left,right); QuickSort(strs,left,parPos); QuickSort(strs,parPos+1,right); } } //划分 public static int Partition(String strs[],int left,int right){ String x = strs[left];//将最左边的值作为主元 int i = left; for(int j=left+1;j<=right;j++){ String str1 = x+strs[j]; String str2 = strs[j]+x; if(str1.compareTo(str2)>0){ i++; swap(strs,i,j); } } swap(strs,left,i); return i;//返回划分位置 } //交换 public static void swap(String strs[],int i,int j){ String temp = strs[j]; strs[j] = strs[i]; strs[i] = temp; }

测试:

public static void main(String[] args) { int[] array = {3,32,321,5,1,2}; System.out.println(PrintMinNumber(array)); }

转载请注明原文地址: https://www.6miu.com/read-2627486.html

最新回复(0)