1.3 一摞烙饼的排序

一摞烙饼的排序

基本问题

假设有n块大小不一样的烙饼,那么最少要翻动几次,才能达到最终有序的结果。

思路:每次找到最大的然后从将最大的以及最大的上面的反转,这时候最大的在最上面,然后将整个反转,最大的就在最下面了。然后再对除了最下面的n-1个烙饼进行上述的操作,知道全部的烙饼有序。

例如:13524---> 53124--->42135

class Test{
	public static void main(String[] args) {
		// 一摞烙饼
		int[] arr = new int[]{2,3,5,4,1};
		reverse(arr,0,arr.length-1);
		
		// flag表示找了几次最大的值,也就是已经将flag个大饼放在的最下面
		int flag = 0;
		while(flag < arr.length){
			// 找到最大的饼所在的位置
			int index = 0;
			for(int i = 0;i<arr.length - flag;i++){
				if(arr[index] < arr[i]) index = i;
			}
			// 翻转
			reverse(arr,0,index);
			// 再次反转
			reverse(arr,0,arr.length - flag - 1);
			flag++;
		}
		for(int i:arr) System.out.print(i+" ");
		System.out.println();
		
	}
	// 按照索引进行翻转
	public static void reverse(int[] arr,int left,int right){
		while(left < right){
			int tmp = arr[left];
			arr[left] = arr[right];
			arr[right] = tmp;
			left++;
			right--;
		}

	}
}

还有一个解题方案是穷举方案,每一次都将本应该在一起的两个烙饼放在一起,当反转次数大于上述的方法的反转次数也就是\(2(n-1)\)次的时候,放弃这个算法。

拓展问题

1.有一些服务员会把上面的烙饼放在自己的帽子上,然后继续处理其他烙饼,在这个条件下,我们的算法能有什么改进

我的想法是类似于程序中的空间换时间,找到最大的烙饼之后,将最大的烙饼上面的烙饼放在自己的头上,然后只反转自己手里面的烙饼,翻转完成之后,再将头上的烙饼拿下来重新对n-1个烙饼实施上述操作,直到全部有序。

2.有时候,烙饼一面金黄,一面比较焦,让金黄的一面在上面

很简单,就是在每次将最大的烙饼在最上面的时候,判断金黄的一面是否在上面,如果是直接反转,如果不是,先反转最大的烙饼,然后再反转全部的烙饼即可。

3.有一次,师傅烙了3个饼,一个均是金黄,一个均是焦,一个一面焦一面金黄,如果已经知道最上面是焦,则问这个最上面的饼的反面也是焦的概率是多少?

\[result = \frac{1}{2} \]

4. 每次反转烙饼的时候,上面的若干个烙饼会被反转,如果我们希望在排序过程中,翻转烙饼的次数最少,结果会是如何呢?

多用几个帽子

5.目前针对这个问题研究出来的结果

翻转所有饼的最大下界是\(\frac{15}{14} * n\)
翻转所有的病的最小上界是\(\frac{5*n + 5}{3}\)

posted @ 2020-11-18 12:18  BOTAK  阅读(172)  评论(0编辑  收藏  举报