记一次神经病算法优化

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

所以想自己创造 万中无一

写完发现,还是选择千篇一律吧,万中无一实现起来真滴难。。。

 

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

 

 

 

 

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