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
C++
#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;
}
|
Java
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));
}
}
|
Python
def reverse_array(arr, n, p):
for i in range (p, 0 , - 1 ):
arr[:i] = arr[:i][:: - 1 ]
return arr
arr = [ 4 , 2 , 1 , 3 , 5 , 6 ]
n = len (arr)
p = 4
result = reverse_array(arr, n, p)
print (result)
|
C#
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();
}
}
|
Javascript
function reverseArray(arr, n, p)
{
for (let i = p; i > 0; i--)
{
arr = arr.slice(0, i).reverse().concat(arr.slice(i));
}
return arr;
}
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( " " ));
}
main();
|
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++
#include <bits/stdc++.h>
using namespace std;
void find_original_array( int arr[], int n, int p)
{
int r = p - 1;
int l = 0;
int index = 0;
vector< int > res;
while (l <= r) {
if (index % 2 == 0) {
res.push_back(arr[l++]);
}
else {
res.push_back(arr[r--]);
}
index = index + 1;
}
reverse(res.begin(), res.end());
for ( int i = 0; i < res.size(); i++) {
arr[i] = res[i];
}
for ( int i = 0; i < n; i++) {
cout << arr[i] << " " ;
}
}
int main()
{
int arr[] = { 4, 2, 1, 3, 5, 6 }, P = 4;
int n = sizeof (arr) / sizeof (arr[0]);
find_original_array(arr, n, P);
return 0;
}
|
Java
import java.util.*;
public class GFG
{
static void find_original_array( int arr[], int n, int p)
{
int r = p - 1 ;
int l = 0 ;
int index = 0 ;
ArrayList<Integer> res = new ArrayList<Integer>();
while (l <= r) {
if (index % 2 == 0 ) {
res.add(arr[l++]);
}
else {
res.add(arr[r--]);
}
index = index + 1 ;
}
Collections.reverse(res);
for ( int i = 0 ; i < res.size(); i++) {
arr[i] = ( int )res.get(i);
}
for ( int i = 0 ; i < n; i++) {
System.out.print(arr[i] + " " );
}
}
public static void main(String args[])
{
int arr[] = { 4 , 2 , 1 , 3 , 5 , 6 }, P = 4 ;
int n = arr.length;
find_original_array(arr, n, P);
}
}
|
Python3
def find_original_array(arr, n, p):
r = p - 1 ;
l = 0 ;
index = 0 ;
res = []
while (l < = r):
if (index % 2 = = 0 ):
res.append(arr[l]);
l + = 1 ;
else :
res.append(arr[r]);
r - = 1 ;
index = index + 1 ;
res.reverse();
for i in range ( len (res)):
arr[i] = res[i];
for i in range (n):
print (arr[i], end = " " );
if __name__ = = '__main__' :
arr = [ 4 , 2 , 1 , 3 , 5 , 6 ]
P = 4 ;
n = len (arr);
find_original_array(arr, n, P);
|
C#
using System;
using System.Collections;
class GFG
{
static void find_original_array( int []arr, int n, int p)
{
int r = p - 1;
int l = 0;
int index = 0;
ArrayList res = new ArrayList();
while (l <= r) {
if (index % 2 == 0) {
res.Add(arr[l++]);
}
else {
res.Add(arr[r--]);
}
index = index + 1;
}
res.Reverse();
for ( int i = 0; i < res.Count; i++) {
arr[i] = ( int )res[i];
}
for ( int i = 0; i < n; i++) {
Console.Write(arr[i] + " " );
}
}
public static void Main()
{
int []arr = { 4, 2, 1, 3, 5, 6 };
int P = 4;
int n = arr.Length;
find_original_array(arr, n, P);
}
}
|
Javascript
<script>
const find_original_array = (arr, n, p) => {
let r = p - 1;
let l = 0;
let index = 0;
let res = [];
while (l <= r) {
if (index % 2 == 0) {
res.push(arr[l++]);
}
else {
res.push(arr[r--]);
}
index = index + 1;
}
res.reverse();
for (let i = 0; i < res.length; i++) {
arr[i] = res[i];
}
for (let i = 0; i < n; i++) {
document.write(`${arr[i]} `);
}
}
let arr = [4, 2, 1, 3, 5, 6], P = 4;
let n = arr.length;
find_original_array(arr, n, P);
</script>
|
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)