网上搜到的答案都是 千篇一律
所以想自己创造 万中无一
写完发现,还是选择千篇一律吧,万中无一实现起来真滴难。。。
链接:http://blog.youkuaiyun.com/zyx520ytt/article/details/72466255
题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323
======== 千篇一律 ======
思路:爆破法
实现:把数组转成list,然后对list进行排序
代码:假定num1 = 9, num2 = 1,很明显 result1 = 91, result2 = 19
对比 result1和result2来对num1和num2排序
Collections.sort(list,new Comparator<Integer>() {
public int compare(Integer num1, Integer num2) {
String result1 = num1 + "" + num2;
String result2 = num2 + ""+ num1;
return result1.compareTo(result2);
}
});
======== 万里无一 ========
思路:逆推法 + 分组 + 补位法
实现:1开头的数字和9开头的数字拼成的数字,哪个大?肯定9开头的数字放前面大
比如19和91,拼出来的数字是19 91 和 91 19, 必然9开头的数字放前面大
所以有了分组的思路,用数字的首位来分组,分9组,1到9
这样,可以减少首位数字不同还要比较的排序,这些排序都是不必要的
分组以后,出现一个问题,怎么比较,怎么排
84 和 8 一起的时候,可以排成 84 8,还有 8 84
为什么8要排在84的后面,完全没思路啊
难道只能和他一样,用 num1 + num2 和 num2 + num2 比较?
在地铁上我发现一个规律,可以先对8补位x,x = 8
那么8x就要排在84的后面
验证一下,假如 8 和 89在一起,可以排成 8 89 和 89 8
补位 x = 8 之后,8x 要排在89之前
完美规避num1 + num2 和 num2 + num1 对比的问题
再次验证一下: 47 和 414拼接,可以拼成 47 414 和 414 47
补位:x = 4, 47x 比 414大,47x 排在 414 之后
完全没有问题
代码:放在最最最后面了
总结:1、万级别以下,我的速度不如他,因为存在很多String的操作
万级别以上,开始超越他,并且秒杀他,因为我减少了大概20%的比较量
2、直接对list.get(0)重新赋值会编译报错,如果是基本类型和String可以先取出,然后赋值,最后存入
如果是对象类型,直接取出然后赋值即可
3、我现在的代码有个非常大的问题
就是补位使用了字符串来补
字符串和数字之间的转换有点消耗性能
所以可以改成完全用int来计算,来补位等等,或许速度会更快
4、重要的是思路和规律
代码不是经过优化后的最佳代码
比如
for(int i = 0; i < list.size(); i++){
} // 可以优化成如下代码,以减少调用list.size()的次数
int size = list.size();
for(int i = 0; i < size ; i++){
}
又比如
List<String> list = new ArrayList<>(); // 可以预先指定list的初始长度
List<String> list = new ArrayList<>(99);
又或是计算数字的位数,完全可以使用Math.log10(num)或者while来计算,不必先转成String,再求str.length();
public class TestJava {
private static String x = "x";
private static String xx = "xx";
private static String xxx = "xxx";
private static String xxxx = "xxxx";
private static String xxxxx = "xxxxx";
private static String xxxxxx = "xxxxxx";
private static String xxxxxxx = "xxxxxxx";
private static String xxxxxxxx = "xxxxxxxx";
public static void main(String args[]) {
int bb[] = new int[9999999];
createRandomArray(bb);
long startTime3 = System.currentTimeMillis();
String c = jiejingAlgorithm(bb);
// System.out.println("最小的数是" + c.substring(0, 300));
System.out.println("我的代码耗时 time = " + (System.currentTimeMillis() - startTime3));
}
private static String jiejingAlgorithm(int[] listlistlistlist) {
String tempNumber = "";
int shou = 0;
int mapSize = 9;
long startTime = System.currentTimeMillis();
Map<String, List<String>> map = new HashMap(mapSize);
for (int i = 0; i < mapSize; i++) {
map.put(i + "", new ArrayList<String>());
}
for (int i = 0; i < listlistlistlist.length; i++) {
shou = listlistlistlist[i];
tempNumber = shou + "";
for (int j = 0; j < tempNumber.length() - 1; j++) {
shou = shou / 10;
}
map.get((shou - 1) + "").add(tempNumber);
}
startTime = System.currentTimeMillis();
final int count[] = { 0 };
for (int i = 0; i < map.size(); i++) {
long tempStartTime = System.currentTimeMillis();
tempStartTime = System.currentTimeMillis();
List<String> list = map.get(i + "");
/**
* 获取该组中最大的长度
*/
int maxLength = 0;
for (int j = 0; j < list.size(); j++) {
String str = list.get(j);
int strLen = str.length();
if (strLen > maxLength) {
maxLength = strLen;
}
}
tempStartTime = System.currentTimeMillis();
/**
* 比最大长度短的字符串都拼接上x
*/
for (int j = 0; j < list.size(); j++) {
String str = list.get(j);
int strLen = str.length();
if (strLen < maxLength) {
String tempXX = "";
switch (maxLength - strLen) {
case 1:
tempXX = x;
break;
case 2:
tempXX = xx;
break;
case 3:
tempXX = xxx;
break;
case 4:
tempXX = xxxx;
break;
case 5:
tempXX = xxxxx;
break;
case 6:
tempXX = xxxxxx;
break;
case 7:
tempXX = xxxxxxx;
break;
case 8:
tempXX = xxxxxxxx;
break;
}
str = str + tempXX;
list.set(j, str);
}
}
tempStartTime = System.currentTimeMillis();
/**
* 对组排序,x等同于首位数字
*/
final int finalI = i;
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
count[0]++;
if (o1.contains("x")) {
o1 = o1.replaceAll("x", finalI + 1 + "");
}
if (o2.contains("x")) {
o2 = o2.replaceAll("x", finalI + 1 + "");
}
return o1.compareTo(o2);
}
});
}
startTime = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < map.size(); i++) {
Iterator<String> iterator = map.get(i + "").iterator();
while (iterator.hasNext()) {
String temp = iterator.next();
if (temp.contains("x")) {
temp = temp.replaceAll("x", "");
}
stringBuilder.append(temp).append(" ");
}
}
startTime = System.currentTimeMillis();
String result = stringBuilder.toString();
return result;
}
private static void createRandomArray(int arr[]) {
int max = 9999999;
int min = 1;
for (int i = 0; i < arr.length; i++) {
arr[i] = new Random().nextInt(max) % (max - min + 1) + min;
}
System.out.println("创建完成");
}
}