从 P 前缀反转后获得的给定数组中找到原始数组
给定一个大小为N的数组arr[]和一个整数P (P < N),任务是从通过P 个前缀反转获得的数组中找到原始数组,其中在第 i 个反转中,包含索引的数组的大小为 i 的前缀范围[0, i-1]被反转。
例子:
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
朴素方法:为了解决这个问题,在每个步骤中反转大小为i的前缀,对于范围[1,P]中的i ,从P大小的前缀开始,然后逐渐减小大小。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效方法:此解决方案基于两个指针方法。由于只有P个前缀反转,因此数组的前P个元素只会受到影响,其余的保持不变。因此,在P前缀反转之后,可以观察到原始数组和数组的模式。只应修改前P个元素。按照以下步骤解决上述问题:
- 初始化两个变量l = 0和r = P-1
- 初始化向量res以存储修改后的前缀和index = 0以跟踪奇数和偶数索引处的元素。
- 使用 while 循环遍历arr[] 的前缀。
- 如果索引甚至将arr[l]推入向量 res 并增加l 。
- 否则将arr[r]推入向量res并递减r 。
- 也增加索引。
- 现在反转res并将修改后的前缀分配给 arr 的长度为 p 的前缀。
- 打印原始数组。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
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 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
// 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 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
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.
Python3
# 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#
// 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.
Javascript
1 2 3 4 5 6
时间复杂度: O(N),其中 N 是数组的长度。
辅助空间: O(N)