1.3 翻烙饼问题
来源:互联网 发布:windows 查看进程数 编辑:程序博客网 时间:2024/04/27 13:23
1. 前言
本文的一些图片, 资料 截取自编程之美
2. 问题描述
3. 问题分析
书上提供了两种思路
一种 : 就是每一次用两次交换将当前最大的烙饼翻到最下面
另一种 : 是递归穷举, 上界为上面的分析出的(2 * (n - 1))
但是, 我这里并没有实现递归穷举的算法, 我这里实现的另一种思路是 : 将相邻的有序的数字(们), 一起翻转, 但是从效果上来看,貌似这个思路, 和第一个思路相差不大呀
4. 代码
/** * file name : Test28SortPie.java * created at : 10:58:38 AM May 10, 2015 * created by 970655147 */package com.hx.test02;public class Test28SortPie { // 翻烙饼问题 public static void main(String []args) { long start = System.currentTimeMillis();// int pie[] = {0, 4, 5, 2, 1, 6, 7, 3, 9, 8, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10 }; int pie[] = {40, 67, 99, 31, 9, 84, 89, 58, 74, 13, 33, 2, 92, 85, 24, 95, 52, 93, 22, 12, 45, 21, 96, 39, 10, 68, 46, 90, 23, 64, 51, 78, 100, 32, 87, 41, 71, 82, 37, 6, 18, 80, 59, 77, 28, 42, 73, 72, 98, 91, 50, 60, 53, 83, 86, 63, 70, 88, 17, 11, 69, 14, 19, 4, 1, 16, 29, 30, 34, 94, 38, 76, 55, 36, 5, 66, 75, 20, 44, 35, 56, 8, 25, 7, 49, 26, 61, 47, 15, 27, 54, 97, 48, 43, 65, 79, 3, 81, 62, 57 }; print(pie);// sortPie(pie); sortPie02(pie); print(pie); long spent = System.currentTimeMillis() - start; System.out.println("spent : " + spent + " ms"); } // 每次将最大的烙饼先翻到最上面 在翻到"最下面" // 将当前最大的元素 翻转到最上面, 然后在反转到最下面 public static void sortPie(int[] pie) { int cnt = 0; int step = pie.length - 1; for(; step > 0; step --) { int index = findMaxValueIndex(pie, step); if(index != step) { if(index != 0) { revert(pie, 0, index); cnt ++; } revert(pie, 0, step); cnt ++; } } System.out.println("reverted : " + cnt + " times..."); }// // 注意 : pie最好按照其大小编号[比如最小的为1号, 次小的为2号, ...], 因为这里判断是否是小于当前最大值的依据是前一个数或者后一个数是否是(当前的数-1)// // 每次将最大的烙饼先翻到最上面 在翻到"最下面"// // 不过如果存在有序的序列 将该序列的烙饼翻到合适的地方 详见代码 public static void sortPie02(int[] pie) { int cnt = 0; int step = pie.length - 1; while(step > 0) {// print(pie); boolean existsSeq = false; int maxIdx = findMaxValueIndex(pie, step); int idxBefore = -1, idxAfter = -1; int endOfSortedIdx = -1; for(idxBefore=maxIdx; (idxBefore>0) && ((pie[idxBefore-1]+1) == pie[maxIdx]); idxBefore -- ) ; for(idxAfter=maxIdx; (idxAfter<step) && ((pie[idxAfter+1]+1) == pie[maxIdx]); idxAfter ++ ) ; if((idxAfter - maxIdx) < (maxIdx - idxBefore) ) { endOfSortedIdx = idxBefore; } else { endOfSortedIdx = idxAfter; } if(endOfSortedIdx == idxBefore) { // ..., idxBefore, ..., maxIdx, ... // 有序的共有((maxIdx - endOfSortedIdx) + 1) 个元素 if(maxIdx != step) { revert(pie, 0, maxIdx); revert(pie, 0, step); cnt += 2; } step = step - ((maxIdx - endOfSortedIdx) + 1); } else { // ..., maxIdx, ..., idxAfter, ... // 有序的共有((idxAfter - maxIdx) + 1) 个元素 if(maxIdx == 0) { revert(pie, 0, endOfSortedIdx); cnt ++; } else { revert(pie, 0, endOfSortedIdx); revert(pie, 0, (idxAfter-maxIdx)); cnt += 2; } revert(pie, 0, step); cnt ++; step = step - ((endOfSortedIdx - maxIdx) + 1); } } System.out.println("reverted : " + cnt + " times..."); } public static void revert(int[] pie, int start, int end) { System.out.println(start + " -> " + end); // 将start -> end的数据翻转 for(int i=start, j=end; i<j; i++, j--) { int t = pie[i]; pie[i] = pie[j]; pie[j] = t; } } // 找到数组中最大的值 public static int findMaxValueIndex(int[] pie) { int index = 0; int maxVal = Integer.MIN_VALUE; for(int i=0; i<pie.length; i++) { if(pie[i] > maxVal) { index = i; maxVal = pie[i]; } } return index; } // 找到数组中前depth个数据中最大的元素的索引 public static int findMaxValueIndex(int[] pie, int depth) { int index = 0; int maxVal = Integer.MIN_VALUE; for(int i=0; i<=depth; i++) { if(pie[i] > maxVal) { index = i; maxVal = pie[i]; } } return index; } // 找到数组中小于max的值的最大的值的索引 public static int findMaxValueIndexWithInMax(int[] pie, int max) { int index = 0; int maxVal = Integer.MIN_VALUE; for(int i=0; i<pie.length; i++) { if(pie[i] > maxVal && pie[i] < max) { index = i; maxVal = pie[i]; } } return index; } public static void print(int[] arr) { StringBuilder sb = new StringBuilder(arr.length * 10);// for(int i=0; i<arr.length; i++) {// sb.append(i + " ");// }// sb.append("\r\n"); for(int i=0; i<arr.length; i++) { sb.append(arr[i] + " "); } System.out.println(sb.toString()); }}
5. 运行结果
6. 总结
常规的思路, 不是那么难想出来, 但是要想找出一种非常好的算法,就太难了
注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!
0 0
- 1.3 翻烙饼问题
- 翻烙饼问题
- 翻烙饼问题
- 翻烙饼问题
- 编程之美-翻烙饼问题
- 编程之美读书笔记:翻烙饼的问题
- 1.3一摞烙饼的问题
- 烙饼排序问题
- 编程之美 - 1.3 翻烙饼 书中代码可运行版 ,看懂了没自己写
- 一摞烙饼的问题
- 烙饼问题与搜索树
- 编程之美 - 烙饼问题
- 编程之美1.3 一摞烙饼的排序(扩展问题)
- 编程之美-- 烙饼排序问题
- 关于烙饼排序问题的优化
- 编程之美之烙饼问题
- 编程之美-- 烙饼排序问题
- 编程之美 一摞烙饼问题
- wget使用cookies
- Hadoop简介
- jquery基础学习之变量命名不污染的方法总结
- poj3268(线段树)
- HDU 2157 How many ways??
- 1.3 翻烙饼问题
- HTML5 入门--1
- HDU 5365 Run (判断正四边形)
- 初识MVC之建项
- Network Saboteur
- 剑指Offer面试题36(Java版):数组中的逆序对
- JVM虚拟机结构
- Android-扩展BaseAdapter实现progressBar下载
- OC中字典