题目及测试
package sword033;
/* 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,
* 打印能拼接出的所有数字中最小的一个。
* 例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字321323.
*/
public class main {
public static void main(String[] args) {
int[][] testTable = {{3,32,321},{3,12,121,5,9}};
for (int[] ito : testTable) {
test(ito);
}
}
private static void test(int[] ito) {
Solution solution = new Solution();
String rtn;
long begin = System.currentTimeMillis();
for (int i = 0; i < ito.length; i++) {
System.out.print(ito[i]+" ");
}//开始时打印数组
System.out.println();
rtn = solution.printMinNumber(ito);//执行程序
long end = System.currentTimeMillis();
System.out.println("rtn=" + rtn);
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法1(成功)
方法1:比较Integer类型
m和n,如果长度相同,按位比较即可。
如果长度不同,先比较前min(lengthM,lengthN)位,按位比较即可。
如果前面都相同,只能比较m*10^(log10 n)+n和n*10^(log10 m)+m,相当于比较字符串mn和nm的大小
方法2:采用比较数组中字符串大小的方法。
根据题目要求,两个数字m和n能拼接成数字mn和数字nm,如果mn<nm那么说明m应该排在n前面,我们应该打印出mn;反之,如果nm<mn,我们定义n小于m.r如果mn=nm,则表示m和n大小相等。
Java中,compareTO函数能够按照字典顺序将两个字符串相比较,返回一个int型。因此,可以先将整数数组转化为字符串数组,然后再采用Collections.sort()函数排序比较后的字符串大小。
package sword033;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Solution {
public String printMinNumber(int[] nums) {
int length = nums.length;
if(length == 0) {
return "0";
}
if(length == 1) {
return String.valueOf(nums[0]);
}
List<Integer> list = new ArrayList<Integer>(nums.length);
for(int i=0;i<length;i++) {
list.add(nums[i]);
}
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
int lengthA = lengthOfInt(a);
int lengthB = lengthOfInt(b);
if(lengthA == lengthB) {
return comparePreN(a, b, lengthA, lengthA, lengthB);
}
if(lengthA < lengthB) {
int result = comparePreN(a, b, lengthA, lengthA, lengthB);
if(result != 0) {
return result;
}else {
return comparePreN(a * num10[lengthB] + b, b * num10[lengthA] + a, lengthA+lengthB, lengthA+lengthB, lengthA+lengthB);
}
}else {
int result = comparePreN(a, b, lengthB, lengthA, lengthB);
if(result != 0) {
return result;
}else {
return comparePreN(a * num10[lengthB] + b, b * num10[lengthA] + a, lengthA+lengthB, lengthA+lengthB, lengthA+lengthB);
}
}
}
});
StringBuilder builder = new StringBuilder();
for(int i=0;i<length;i++) {
builder.append(list.get(i));
}
return builder.toString();
}
// 比较a和b的前n位大小,a小,返回小于0,a大,返回大于0,而且保证a和b有前n位
private int comparePreN(int a,int b,int n,int lengthA,int lengthB) {
for(int i=0;i<n;i++) {
int nowA = a/num10[lengthA];
int nowB = b/num10[lengthB];
if(nowA > nowB) {
return 1;
}
if(nowB > nowA) {
return -1;
}
a = a - nowA * num10[lengthA];
b = b - nowB * num10[lengthB];
lengthA--;
lengthB--;
}
return 0;
}
int[] num10 = new int[] {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
// 计算num的长度
private int lengthOfInt(int num) {
for(int i=0;i<num10.length;i++) {
if(num < num10[i]) {
return i;
}
}
return 10;
}
}
package sword033;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Solution {
public String printMinNumber(int[] nums) {
int length = nums.length;
if(length == 0) {
return "0";
}
if(length == 1) {
return String.valueOf(nums[0]);
}
List<Integer> list = new ArrayList<Integer>(nums.length);
for(int i=0;i<length;i++) {
list.add(nums[i]);
}
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
String ab = String.valueOf(a) + String.valueOf(b);
String ba = String.valueOf(b) + String.valueOf(a);
return Long.valueOf(ab) < Long.valueOf(ba)?1:-1;
}
});
StringBuilder builder = new StringBuilder();
for(int i=0;i<length;i++) {
builder.append(list.get(i));
}
return builder.toString();
}
}