A Pancake Sorting Problem
Last Updated :
30 Dec, 2022
We have discussed Pancake Sorting in the previous post. Following is a problem based on Pancake Sorting.
Given an unsorted array, sort the given array. You are allowed to do only following operation on array.
flip(arr, i): Reverse array from 0 to i
Imagine a hypothetical machine where flip(i) always takes O(1) time. Write an efficient program for sorting a given array in O(nLogn) time on the given machine. If we apply the same algorithm here, the time taken will be O(n^2) because the algorithm calls findMax() in a loop and find findMax() takes O(n) time even on this hypothetical machine.
We can use insertion sort that uses binary search. The idea is to run a loop from second element to last element (from i = 1 to n-1), and one by one insert arr[i] in arr[0..i-1] (like standard insertion sort algorithm). When we insert an element arr[i], we can use binary search to find position of arr[i] in O(Logi) time. Once we have the position, we can use some flip operations to put arr[i] at its new place. Following are abstract steps.
// Standard Insertion Sort Loop that starts from second element
for (i=1; i O(n)
{
int key = arr[i];
// Find index of ceiling of arr[i] in arr[0..i-1] using binary search
j = celiSearch(arr, key, 0, i-1); ----> O(logn) (See this)
// Apply some flip operations to put arr[i] at correct place
}
Since flip operation takes O(1) on given hypothetical machine, total running time of above algorithm is O(nlogn). Thanks to Kumar for suggesting above problem and algorithm.
Let us see how does the above algorithm work. ceilSearch() actually returns the index of the smallest element which is greater than arr[i] in arr[0..i-1]. If there is no such element, it returns -1. Let the returned value be j. If j is -1, then we don't need to do anything as arr[i] is already the greatest element among arr[0..i]. Otherwise we need to put arr[i] just before arr[j].
So how to apply flip operations to put arr[i] just before arr[j] using values of i and j. Let us take an example to understand this. Let i be 6 and current array be {12, 15, 18, 30, 35, 40, 20, 6, 90, 80}. To put 20 at its new place, the array should be changed to {12, 15, 18, 20, 30, 35, 40, 6, 90, 80}. We apply following steps to put 20 at its new place.
1) Find j using ceilSearch (In the above example j is 3).
2) flip(arr, j-1) (array becomes {18, 15, 12, 30, 35, 40, 20, 6, 90, 80})
3) flip(arr, i-1); (array becomes {40, 35, 30, 12, 15, 18, 20, 6, 90, 80})
4) flip(arr, i); (array becomes {20, 18, 15, 12, 30, 35, 40, 6, 90, 80})
5) flip(arr, j); (array becomes {12, 15, 18, 20, 30, 35, 40, 6, 90, 80})
Following is the implementation of the above algorithm.
C++
// C++ program of Pancake Sorting Problem
#include<bits/stdc++.h>
using namespace std;
/* A Binary Search based function to
get index of ceiling of x in
arr[low..high] */
int ceilSearch(int arr[], int low, int high, int x)
{
int mid;
/* If x is smaller than or equal
to the first element,
then return the first element */
if(x <= arr[low])
return low;
/* If x is greater than the
last element, then return -1 */
if(x > arr[high])
return -1;
/* get the index of middle
element of arr[low..high]*/
mid = (low + high)/2; /* low + (high – low)/2 */
/* If x is same as middle
element, then return mid */
if(arr[mid] == x)
return mid;
/* If x is greater than arr[mid],
then either arr[mid + 1]
is ceiling of x, or ceiling
lies in arr[mid+1...high] */
if(arr[mid] < x)
{
if(mid + 1 <= high && x <= arr[mid+1])
return mid + 1;
else
return ceilSearch(arr, mid+1, high, x);
}
/* If x is smaller than arr[mid], then either arr[mid]
is ceiling of x or ceiling lies in arr[mid-1...high] */
if (mid - 1 >= low && x > arr[mid-1])
return mid;
else
return ceilSearch(arr, low, mid - 1, x);
}
/* Reverses arr[0..i] */
void flip(int arr[], int i)
{
int temp, start = 0;
while (start < i)
{
temp = arr[start];
arr[start] = arr[i];
arr[i] = temp;
start++;
i--;
}
}
/* Function to sort an array using
insertion sort, binary search and flip */
void insertionSort(int arr[], int size)
{
int i, j;
// Start from the second element
// and one by one insert arr[i]
// in already sorted arr[0..i-1]
for(i = 1; i < size; i++)
{
// Find the smallest element in arr[0..i-1]
// which is also greater than
// or equal to arr[i]
int j = ceilSearch(arr, 0, i-1, arr[i]);
// Check if there was no element
// greater than arr[i]
if (j != -1)
{
// Put arr[i] before arr[j] using
// following four flip operations
flip(arr, j-1);
flip(arr, i-1);
flip(arr, i);
flip(arr, j);
}
}
}
/* A utility function to print an array of size n */
void printArray(int arr[], int n)
{
int i;
for (i = 0; i < n; ++i)
cout<<arr[i]<<" ";
}
/* Driver code */
int main()
{
int arr[] = {18, 40, 35, 12, 30, 35, 20, 6, 90, 80};
int n = sizeof(arr)/sizeof(arr[0]);
insertionSort(arr, n);
printArray(arr, n);
return 0;
}
// This code is contributed by rathbhupendra
C
// C program of Pancake Sorting Problem
#include <stdlib.h>
#include <stdio.h>
/* A Binary Search based function to get index of ceiling of x in
arr[low..high] */
int ceilSearch(int arr[], int low, int high, int x)
{
int mid;
/* If x is smaller than or equal to the first element,
then return the first element */
if(x <= arr[low])
return low;
/* If x is greater than the last element, then return -1 */
if(x > arr[high])
return -1;
/* get the index of middle element of arr[low..high]*/
mid = (low + high)/2; /* low + (high – low)/2 */
/* If x is same as middle element, then return mid */
if(arr[mid] == x)
return mid;
/* If x is greater than arr[mid], then either arr[mid + 1]
is ceiling of x, or ceiling lies in arr[mid+1...high] */
if(arr[mid] < x)
{
if(mid + 1 <= high && x <= arr[mid+1])
return mid + 1;
else
return ceilSearch(arr, mid+1, high, x);
}
/* If x is smaller than arr[mid], then either arr[mid]
is ceiling of x or ceiling lies in arr[mid-1...high] */
if (mid - 1 >= low && x > arr[mid-1])
return mid;
else
return ceilSearch(arr, low, mid - 1, x);
}
/* Reverses arr[0..i] */
void flip(int arr[], int i)
{
int temp, start = 0;
while (start < i)
{
temp = arr[start];
arr[start] = arr[i];
arr[i] = temp;
start++;
i--;
}
}
/* Function to sort an array using insertion sort, binary search and flip */
void insertionSort(int arr[], int size)
{
int i, j;
// Start from the second element and one by one insert arr[i]
// in already sorted arr[0..i-1]
for(i = 1; i < size; i++)
{
// Find the smallest element in arr[0..i-1] which is also greater than
// or equal to arr[i]
int j = ceilSearch(arr, 0, i-1, arr[i]);
// Check if there was no element greater than arr[i]
if (j != -1)
{
// Put arr[i] before arr[j] using following four flip operations
flip(arr, j-1);
flip(arr, i-1);
flip(arr, i);
flip(arr, j);
}
}
}
/* A utility function to print an array of size n */
void printArray(int arr[], int n)
{
int i;
for (i = 0; i < n; ++i)
printf("%d ", arr[i]);
}
/* Driver program to test insertion sort */
int main()
{
int arr[] = {18, 40, 35, 12, 30, 35, 20, 6, 90, 80};
int n = sizeof(arr)/sizeof(arr[0]);
insertionSort(arr, n);
printArray(arr, n);
return 0;
}
Java
// Java program of Pancake Sorting Problem
import java.io.*;
public class GfG {
/* A Binary Search based function to get index of ceiling of x in
arr[low..high] */
static int ceilSearch(int arr[], int low, int high, int x)
{
int mid;
/* If x is smaller than or equal to the first element,
then return the first element */
if(x <= arr[low])
return low;
/* If x is greater than the last element, then return -1 */
if(x > arr[high])
return -1;
/* get the index of middle element of arr[low..high]*/
// low + (high - low)/2
mid = (low + high)/2;
/* If x is same as middle element, then return mid */
if(arr[mid] == x)
return mid;
/* If x is greater than arr[mid], then either arr[mid + 1]
is ceiling of x, or ceiling lies in arr[mid+1...high] */
if(arr[mid] < x)
{
if(mid + 1 <= high && x <= arr[mid+1])
return mid + 1;
else
return ceilSearch(arr, mid+1, high, x);
}
/* If x is smaller than arr[mid], then either arr[mid]
is ceiling of x or ceiling lies in arr[mid-1...high] */
if (mid - 1 >= low && x > arr[mid-1])
return mid;
else
return ceilSearch(arr, low, mid - 1, x);
}
/* Reverses arr[0..i] */
static void flip(int arr[], int i)
{
int temp, start = 0;
while (start < i)
{
temp = arr[start];
arr[start] = arr[i];
arr[i] = temp;
start++;
i--;
}
}
/* Function to sort an array using insertion sort, binary search and flip */
static void insertionSort(int arr[], int size)
{
int i;
// Start from the second element and one by one insert arr[i]
// in already sorted arr[0..i-1]
for(i = 1; i < size; i++)
{
// Find the smallest element in arr[0..i-1] which is also greater than
// or equal to arr[i]
int j = ceilSearch(arr, 0, i-1, arr[i]);
// Check if there was no element greater than arr[i]
if (j != -1)
{
// Put arr[i] before arr[j] using following four flip operations
flip(arr, j-1);
flip(arr, i-1);
flip(arr, i);
flip(arr, j);
}
}
}
/* A utility function to print an array of size n */
static void printArray(int arr[], int n)
{
int i;
for (i = 0; i < n; ++i)
System.out.print(arr[i] + " ");
}
/* Driver program to test insertion sort */
public static void main(String[] args)
{
int arr[] = {18, 40, 35, 12, 30, 35, 20, 6, 90, 80};
int n = arr.length;
insertionSort(arr, n);
printArray(arr, n);
}
}
Python3
# Python program of Pancake Sorting Problem
#A Binary Search based function to get index of ceiling of x in arr[low..high]
def ceilSearch(arr,low,high,x):
#If x is smaller than or equal to the first element,
#then return the first element
if x <= arr[low]:
return low
#If x is greater than the last element, then return -1
if x > arr[high]:
return -1
#get the index of middle element of arr[low..high]
mid = (low + high)//2 #low + (high-low)/2
#If x is same as middle element, then return mid
if(arr[mid] == x):
return mid
#If x is greater than arr[mid], then either arr[mid + 1]
#is ceiling of x, or ceiling lies in arr[mid+1...high]
if(arr[mid] < x):
if(mid + 1 <= high and x <= arr[mid+1]):
return mid + 1
else:
return ceilSearch(arr, mid+1, high, x)
#If x is smaller than arr[mid], then either arr[mid]
#is ceiling of x or ceiling lies in arr[mid-1...high]
if (mid - 1 >= low and x > arr[mid-1]):
return mid
else:
return ceilSearch(arr, low, mid - 1, x)
#Reverses arr[0..i] */
def flip(arr,i):
start = 0;
while (start < i):
temp = arr[start]
arr[start] = arr[i]
arr[i] = temp
start+=1
i-=1
#Function to sort an array using insertion sort, binary search and flip
def insertionSort(arr):
#Start from the second element and one by one insert arr[i]
#in already sorted arr[0..i-1]
for i in range(1,len(arr)):
#Find the smallest element in arr[0..i-1] which is also greater than
#or equal to arr[i]
j = ceilSearch(arr, 0, i-1, arr[i])
#Check if there was no element greater than arr[i]
if (j != -1):
#Put arr[i] before arr[j] using following four flip operations
flip(arr, j-1)
flip(arr, i-1)
flip(arr, i)
flip(arr, j)
# A utility function to print an array of size n
def printArray(arr):
for i in range(0,len(arr)):
print (arr[i],end=" ")
#Driver function to test above function
arr=[18, 40, 35, 12, 30, 35, 20, 6, 90, 80]
insertionSort(arr)
printArray(arr)
#This code is contributed by Devesh Agrawal
C#
// C# program of Pancake Sorting Problem
using System;
class GFG
{
// A Binary Search based function to get
// index of ceiling of x in arr[low..high]
static int ceilSearch(int []arr, int low,
int high, int x)
{
int mid;
// If x is smaller than or equal to
// the first element,
// then return the first element
if(x <= arr[low])
return low;
// If x is greater than the last element,
// then return -1
if(x > arr[high])
return -1;
// get the index of middle element
// of arr[low..high]
// low + (high - low)/2
mid = (low + high) / 2;
// If x is same as middle element,
// then return mid
if(arr[mid] == x)
return mid;
// If x is greater than arr[mid],
// then either arr[mid + 1] is ceiling of x,
// or ceiling lies in arr[mid+1...high]
if(arr[mid] < x)
{
if(mid + 1 <= high && x <= arr[mid + 1])
return mid + 1;
else
return ceilSearch(arr, mid + 1, high, x);
}
// If x is smaller than arr[mid],
// then either arr[mid] is ceiling of x
// or ceiling lies in arr[mid-1...high]
if (mid - 1 >= low && x > arr[mid - 1])
return mid;
else
return ceilSearch(arr, low, mid - 1, x);
}
// Reverses arr[0..i]
static void flip(int []arr, int i)
{
int temp, start = 0;
while (start < i)
{
temp = arr[start];
arr[start] = arr[i];
arr[i] = temp;
start++;
i--;
}
}
// Function to sort an array using insertion sort,
// binary search and flip
static void insertionSort(int []arr, int size)
{
int i;
// Start from the second element and
// one by one insert arr[i] in
// already sorted arr[0..i-1]
for(i = 1; i < size; i++)
{
// Find the smallest element in arr[0..i-1]
// which is also greater than or equal to arr[i]
int j = ceilSearch(arr, 0, i - 1, arr[i]);
// Check if there was no element greater than arr[i]
if (j != -1)
{
// Put arr[i] before arr[j] using
// following four flip operations
flip(arr, j - 1);
flip(arr, i - 1);
flip(arr, i);
flip(arr, j);
}
}
}
// A utility function to print an array of size n
static void printArray(int []arr, int n)
{
int i;
for (i = 0; i < n; ++i)
Console.Write(arr[i] + " ");
}
// Driver Code
public static void Main(String[] args)
{
int []arr = {18, 40, 35, 12, 30,
35, 20, 6, 90, 80};
int n = arr.Length;
insertionSort(arr, n);
printArray(arr, n);
}
}
// This code is contributed by Princi Singh
JavaScript
<script>
// Javascript program of Pancake Sorting Problem
/* A Binary Search based function to
get index of ceiling of x in
arr[low..high] */
function ceilSearch(arr, low, high, x)
{
var mid;
/* If x is smaller than or equal
to the first element,
then return the first element */
if(x <= arr[low])
return low;
/* If x is greater than the
last element, then return -1 */
if(x > arr[high])
return -1;
/* get the index of middle
element of arr[low..high]*/
mid = parseInt((low + high)/2); /* low + (high – low)/2 */
/* If x is same as middle
element, then return mid */
if(arr[mid] == x)
return mid;
/* If x is greater than arr[mid],
then either arr[mid + 1]
is ceiling of x, or ceiling
lies in arr[mid+1...high] */
if(arr[mid] < x)
{
if(mid + 1 <= high && x <= arr[mid+1])
return mid + 1;
else
return ceilSearch(arr, mid+1, high, x);
}
/* If x is smaller than arr[mid], then either arr[mid]
is ceiling of x or ceiling lies in arr[mid-1...high] */
if (mid - 1 >= low && x > arr[mid-1])
return mid;
else
return ceilSearch(arr, low, mid - 1, x);
}
/* Reverses arr[0..i] */
function flip( arr, i)
{
var temp, start = 0;
while (start < i)
{
temp = arr[start];
arr[start] = arr[i];
arr[i] = temp;
start++;
i--;
}
}
/* Function to sort an array using
insertion sort, binary search and flip */
function insertionSort( arr, size)
{
var i, j;
// Start from the second element
// and one by one insert arr[i]
// in already sorted arr[0..i-1]
for(i = 1; i < size; i++)
{
// Find the smallest element in arr[0..i-1]
// which is also greater than
// or equal to arr[i]
var j = ceilSearch(arr, 0, i-1, arr[i]);
// Check if there was no element
// greater than arr[i]
if (j != -1)
{
// Put arr[i] before arr[j] using
// following four flip operations
flip(arr, j-1);
flip(arr, i-1);
flip(arr, i);
flip(arr, j);
}
}
}
/* A utility function to print an array of size n */
function printArray(arr, n)
{
var i;
for (i = 0; i < n; ++i)
document.write(arr[i]+" ");
}
var arr = [18, 40, 35, 12, 30, 35, 20, 6, 90, 80];
var n = arr.length;
insertionSort(arr, n);
printArray(arr, n);
// This code is contributed by SoumikMondal
</script>
Output6 12 18 20 30 35 35 40 80 90
Time Complexity: O(n log n)
Auxiliary space: O(log n)
Similar Reads
Array Sorting - Practice Problems
Sorting an array means arranging the elements of the array in a certain order. Generally sorting in an array is done to arrange the elements in increasing or decreasing order. Problem statement: Given an array of integers arr, the task is to sort the array in ascending order and return it, without u
9 min read
Pancake Sorting in Python
Pancake Sorting is a sorting algorithm that involves a scenario where you have a stack of pancakes of varying sizes and you want to sort them by size, with the smallest pancake on top and the largest on the bottom. The only operation allowed to sort the pancakes is to insert a spatula at some point
3 min read
Pancake sorting
Given an unsorted array, the task is to sort the given array. You are allowed to do only following operation on array. flip(arr, i): Reverse array from 0 to i Examples: Input: arr[] = { 23, 10, 20, 11, 12, 6, 7 }Output: { 6, 7, 10, 11, 12, 20, 23} Input: arr[] = { 0, 1, 1, 0, 0 }Output: { 0, 0, 0, 1
15+ min read
Top Sorting Interview Questions and Problems
Here is the collection of the Top 50 list of frequently asked interview questions on Sorting. Problems in this article are divided into three Levels so that readers can practice according to the difficulty level step by step. Easy Problems Duplicates within k distanceMaximum Perimeter TriangleMaximi
5 min read
Two-Color Sorting
Given a string s consisting of n lowercase letters. You have to color all of its characters using two colors such that each index of s is assigned exactly one color. You can swap two adjacent indexes of s that have different colors any number of times. The task is to determine whether you can sort t
9 min read
Dutch National Flag Problem in Python
The Dutch National Flag problem is a popular algorithmic problem proposed by Edsger Dijkstra. The problem is to sort an array consisting of three distinct elements (or "colors") in a single pass through the array. The three elements could be anything, but for simplicity, we'll use 0, 1, and 2. The g
4 min read
Alternate Lower Upper String Sort
Given a string containing lowercase and uppercase letters. Sort it in such a manner that the uppercase and lowercase letters come in an alternate manner but in a sorted way. Examples: Input : bAwutndekWEdkd Output :AbEdWddekkntuw Explanation: Here we can see that letter âAâ, âEâ, âWâ are sorted as w
6 min read
Sort 1 to N by swapping adjacent elements
Given an array arr[] of size n containing a permutation of the integers from 1 to n, and a binary array brr[] of size n â 1 in which you can swap two adjacent elements arr[i] and arr[i+1] only when brr[i] = 1 and brr[i+1] = 1.Examples:Input: arr[] = [1, 2, 5, 3, 4, 6], brr[] = [0, 1, 1, 1, 0]Output:
10 min read
Sorting Algorithms
A Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Distribution Apples
We were given N apple trees and M friends. The ith tree has a[i] apples and it takes b[i] units of energy to pluck an apple from this tree. Find the maximum number of apples while minimizing the energy required to pluck them such that they distribute apples among themselves equally. Examples: Input:
7 min read