Given an array arr[] of size N and an integer P (P < N), the task is to find the original array from the array obtained by P prefix reversals where in ith reversal the prefix of size i of the array containing indices in range [0, i-1] was reversed.
Examples:
Input: arr[] = {4, 2, 1, 3, 5, 6}, P = 4.
Output: 1 2 3 4 5 6
Explanation: {1, 2, 3, 4, 5, 6} on prefix reversal P = 1 converts to {1, 2, 3, 4, 5, 6}.
{1, 2, 3, 4, 5, 6} on prefix reversal P = 2 converts to {2, 1, 3, 4, 5, 6}.
{2, 1, 3, 4, 5, 6} on prefix reversal P = 3 converts to {3, 1, 2, 4, 5, 6}
{3, 1, 2, 4, 5, 6} on prefix reversal P = 4 converts to {4, 2, 1, 3, 5, 6}
So answer is {1, 2, 3, 4, 5, 6}Input: arr[] = {10, 9, 8, 3, 5, 6}, P = 3
Output: 9 8 10 3 5 6
Naive Approach: To solve the problem reverse the prefix of size i in each step for i in range [1, P] starting from the P sized prefix and then gradually decrementing the size.
Algorithm
- Initialize a pointer “end” to N-1.
-
For i in range [P, 1] do the following steps:
- Initialize a pointer “start” to i-1.
- While “start” is less than or equal to “end”, swap the elements at indices “start” and “end” and increment “start” and decrement “end”.
- Reverse the entire array.
Implementation of the above approach
#include <iostream> #include <algorithm> #include <vector> using namespace std;
vector< int > reverse_array(vector< int > arr, int n, int p) {
for ( int i = p; i > 0; i--) {
reverse(arr.begin(), arr.begin() + i);
}
return arr;
} int main() {
vector< int > arr = {4, 2, 1, 3, 5, 6};
int n = arr.size();
int p = 4;
vector< int > result = reverse_array(arr, n, p);
for ( int i = 0; i < n; i++) {
cout << result[i] << " " ;
}
cout << endl;
return 0;
} |
import java.util.Arrays;
public class MyClass {
public static int [] reverseArray( int [] arr, int n, int p) {
for ( int i = p; i > 0 ; i--) {
int [] reversed = new int [i];
for ( int j = 0 ; j < i; j++) {
reversed[j] = arr[j];
}
for ( int j = 0 ; j < i / 2 ; j++) {
int temp = reversed[j];
reversed[j] = reversed[i - j - 1 ];
reversed[i - j - 1 ] = temp;
}
for ( int j = 0 ; j < i; j++) {
arr[j] = reversed[j];
}
}
return arr;
}
public static void main(String[] args) {
int [] arr = { 4 , 2 , 1 , 3 , 5 , 6 };
int n = arr.length;
int p = 4 ;
int [] result = reverseArray(arr, n, p);
System.out.println(Arrays.toString(result));
}
} |
def reverse_array(arr, n, p):
for i in range (p, 0 , - 1 ):
arr[:i] = arr[:i][:: - 1 ]
return arr
# Example usage arr = [ 4 , 2 , 1 , 3 , 5 , 6 ]
n = len (arr)
p = 4
result = reverse_array(arr, n, p)
print (result)
|
// C# code for the above approach using System;
using System.Collections.Generic;
public class MainClass
{ static List< int > reverse_array(List< int > arr, int n, int p)
{
for ( int i = p; i > 0; i--)
{
arr.Reverse(0, i);
}
return arr;
}
public static void Main( string [] args)
{
List< int > arr = new List< int > { 4, 2, 1, 3, 5, 6 };
int n = arr.Count;
int p = 4;
List< int > result = reverse_array(arr, n, p);
foreach ( int num in result)
{
Console.Write(num + " " );
}
Console.WriteLine();
}
} // This code is contributed by Pushpesh Raj |
// Javascript code for the above approach // Define a function that reverses subarrays of an array function reverseArray(arr, n, p)
{ for (let i = p; i > 0; i--)
{
// Reverse the subarray arr[0...i-1] using slice, reverse, and concat methods
arr = arr.slice(0, i).reverse().concat(arr.slice(i));
}
return arr;
} // Define the main function function main() {
const arr = [4, 2, 1, 3, 5, 6];
const n = arr.length;
const p = 4;
const result = reverseArray(arr, n, p);
console.log(result.join( " " ));
} // Call the main function main(); |
[1, 2, 3, 4, 5, 6]
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: This solution is based on two pointer approach. Since there is only P prefix reversals, the first P elements of the array only gets affected remaining remains the same. So a pattern can be observed for the original and the array after P prefix reversals. Only the first P elements should be modified. Follow these steps to solve the above problem:
- Initialize two variables l = 0 and r = P-1
- Initialize a vector res to store the modified prefix and index = 0 to keep track of elements at odd and even indices.
-
Using a while loop iterate through the prefix of arr[].
- If the index is even push arr[l] into the vector res and increment l.
- Else push arr[r] into the vector res and decrement r.
- Increment the index also.
- Now reverse the res and assign the modified prefix to the prefix of length p of arr.
- Print the original array.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
void find_original_array( int arr[], int n, int p)
{ // Initialize the r and l
int r = p - 1;
int l = 0;
// Initialize index = 0
// to track elements at
// odd and even positions
int index = 0;
vector< int > res;
while (l <= r) {
// If index is even
if (index % 2 == 0) {
res.push_back(arr[l++]);
}
// If index is odd
else {
res.push_back(arr[r--]);
}
// Increment index
index = index + 1;
}
// Reverse the res
reverse(res.begin(), res.end());
// Assign the modified prefix to arr
for ( int i = 0; i < res.size(); i++) {
arr[i] = res[i];
}
// Print the array arr
// which is the original array
// modified from the
// prefix reversed array
for ( int i = 0; i < n; i++) {
cout << arr[i] << " " ;
}
} // Driver code int main()
{ int arr[] = { 4, 2, 1, 3, 5, 6 }, P = 4;
int n = sizeof (arr) / sizeof (arr[0]);
// Function call
find_original_array(arr, n, P);
return 0;
} |
// Java program for the above approach import java.util.*;
public class GFG
{ static void find_original_array( int arr[], int n, int p)
{
// Initialize the r and l
int r = p - 1 ;
int l = 0 ;
// Initialize index = 0
// to track elements at
// odd and even positions
int index = 0 ;
ArrayList<Integer> res = new ArrayList<Integer>();
while (l <= r) {
// If index is even
if (index % 2 == 0 ) {
res.add(arr[l++]);
}
// If index is odd
else {
res.add(arr[r--]);
}
// Increment index
index = index + 1 ;
}
// Reverse the res
Collections.reverse(res);
// Assign the modified prefix to arr
for ( int i = 0 ; i < res.size(); i++) {
arr[i] = ( int )res.get(i);
}
// Print the array arr
// which is the original array
// modified from the
// prefix reversed array
for ( int i = 0 ; i < n; i++) {
System.out.print(arr[i] + " " );
}
}
// Driver code
public static void main(String args[])
{
int arr[] = { 4 , 2 , 1 , 3 , 5 , 6 }, P = 4 ;
int n = arr.length;
// Function call
find_original_array(arr, n, P);
}
} // This code is contributed by Samim Hossain Mondal. |
# Python program for the above approach def find_original_array(arr, n, p):
# Initialize the r and l
r = p - 1 ;
l = 0 ;
# Initialize index = 0
# to track elements at
# odd and even positions
index = 0 ;
res = []
while (l < = r):
# If index is even
if (index % 2 = = 0 ):
res.append(arr[l]);
l + = 1 ;
# If index is odd
else :
res.append(arr[r]);
r - = 1 ;
# Increment index
index = index + 1 ;
# Reverse the res
res.reverse();
# Assign the modified prefix to arr
for i in range ( len (res)):
arr[i] = res[i];
# Print array arr
# which is the original array
# modified from the
# prefix reversed array
for i in range (n):
print (arr[i], end = " " );
# Driver code if __name__ = = '__main__' :
arr = [ 4 , 2 , 1 , 3 , 5 , 6 ]
P = 4 ;
n = len (arr);
# Function call
find_original_array(arr, n, P);
# This code is contributed by gauravrajput1 |
// C# program for the above approach using System;
using System.Collections;
class GFG
{ static void find_original_array( int []arr, int n, int p)
{
// Initialize the r and l
int r = p - 1;
int l = 0;
// Initialize index = 0
// to track elements at
// odd and even positions
int index = 0;
ArrayList res = new ArrayList();
while (l <= r) {
// If index is even
if (index % 2 == 0) {
res.Add(arr[l++]);
}
// If index is odd
else {
res.Add(arr[r--]);
}
// Increment index
index = index + 1;
}
// Reverse the res
res.Reverse();
// Assign the modified prefix to arr
for ( int i = 0; i < res.Count; i++) {
arr[i] = ( int )res[i];
}
// Print the array arr
// which is the original array
// modified from the
// prefix reversed array
for ( int i = 0; i < n; i++) {
Console.Write(arr[i] + " " );
}
}
// Driver code
public static void Main()
{
int []arr = { 4, 2, 1, 3, 5, 6 };
int P = 4;
int n = arr.Length;
// Function call
find_original_array(arr, n, P);
}
} // This code is contributed by Samim Hossain Mondal. |
<script> // JavaScript program for the above approach
const find_original_array = (arr, n, p) => {
// Initialize the r and l
let r = p - 1;
let l = 0;
// Initialize index = 0
// to track elements at
// odd and even positions
let index = 0;
let res = [];
while (l <= r) {
// If index is even
if (index % 2 == 0) {
res.push(arr[l++]);
}
// If index is odd
else {
res.push(arr[r--]);
}
// Increment index
index = index + 1;
}
// Reverse the res
res.reverse();
// Assign the modified prefix to arr
for (let i = 0; i < res.length; i++) {
arr[i] = res[i];
}
// Print the array arr
// which is the original array
// modified from the
// prefix reversed array
for (let i = 0; i < n; i++) {
document.write(`${arr[i]} `);
}
}
// Driver code
let arr = [4, 2, 1, 3, 5, 6], P = 4;
let n = arr.length;
// Function call
find_original_array(arr, n, P);
// This code is contributed by rakeshsahni </script> |
1 2 3 4 5 6
Time Complexity: O(N) where N is the length of the array.
Auxiliary Space: O(P) as the maximum size of res can be equal to P only. In a condition, when P=N, auxiliary space can reach to O(N)