《剑指offer—面试题45:把数组排成最小的数》
注明:仅个人学习笔记
需要思考的难点:
1.自定义这个比较规则的有效性该如何证明?参考书上证明。
2.仅仅是拼接整型数字可能会导致大数溢出问题,所以考虑使用字符串表示数字,可以解决大数问题。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
*
*
* 把数组排成最小的数 输入一个正整数数组,把数组里面所有数字拼接起来排成一个数,打印能拼接出来的所有数字中最小的一个
* 例如输入{2,32,321} 则打印出这三个数字能排成的最小数字321323
* 解题思路:
* 先将整型数组转换成String数组,然后将String数组排序,最后将排好序的字符串数组拼接出来。关键就是制定排序规则。
* 排序规则如下:
* 若ab > ba 则 a > b, 若ab < ba 则 a < b, 若ab = ba 则 a = b;
* 解释说明:
* 比如 “3” <”31”但是 “331” > “313”,所以要将二者拼接起来进行比较。所以按照我们自定义的排序规则,”3”>”31”
*/
public class PrintMinNumber45
{
public String PrintMinNumber(int[] numbers)
{
int n;
String s = “”;
ArrayList list = new ArrayList();
n = numbers.length;
// 初始化list,{ 32, 3, 321 };
for (int i = 0; i < n; i++)
{
list.add(numbers[i]);
}
// 按照我们定义的排序规则,将list中的元素进行排序,{321,32,3}递增
Collections.sort(list, new Comparator<Integer>()
{
public int compare(Integer str1, Integer str2)
{
String s1 = str1 + "" + str2;
String s2 = str2 + "" + str1;
return s1.compareTo(s2);// compareTo这默认是按字典序排序,我们比较str1和str2拼接后的数值,依次来决定str1和str2谁大
/*
* *
* 比如,str1 = 321,str2 = 32
* 则s1 = 32132, s2 = 32321, s1 < s2的
* 所以,str1 < str2
*/
}
});
//这里输出一下按自定规则排序好的list{321,32,3}递增
for (int k : list)
{
System.out.println(k);
}
//此时,将排序好的三个数拼接起来,就得到的数组中,所有元素拼接起来的数的最小数
for (int j : list)
{
s += j;
}
return s;
}
public static void main(String[] args)
{
PrintMinNumber45 p = new PrintMinNumber45();
int[] numbers = { 32, 3, 321 };
System.out.println(p.PrintMinNumber(numbers));
}
}