記一次神經病算法優化

網上搜到的答案都是 千篇一律

所以想自己創造 萬中無一

寫完發現,還是選擇千篇一律吧,萬中無一實現起來真滴難。。。

 

鏈接: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("創建完成");
	}
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章