網上搜到的答案都是 千篇一律
所以想自己創造 萬中無一
寫完發現,還是選擇千篇一律吧,萬中無一實現起來真滴難。。。
鏈接:http://blog.csdn.net/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("創建完成");
}
}