给定一个由前N 个自然数排列组成的数组A[] ,如果数组元素A[i]可以与其下一个相邻元素交换,则任务是找到将A[]修改为递增数组所需的最小操作次数元素A[i+1]最多两次。如果无法将数组修改为递增数组,则打印-1 。
例子:
Input: A[] = [2,1,5,3,4]
Output: 3
Explanation:
Operation 1: Swap (Arr[2], Arr[3]). Therefore, A[] modifies to {2, 1, 3, 5, 4}.
Operation 2: Swap(arr[3], arr[4]). Therefore, A[] modifies to {2, 1, 3, 4, 5}.
Operation 3: Swap (arr[0], arr[1]). Therefore, A[] modifies to {1, 2, 3, 4, 5}.
Therefore, the sequence of operations are: {2, 1, 5, 3, 4} → {2, 1, 3, 5, 4} → {2, 1, 3, 4, 5} → {1, 2, 3, 4, 5}
Input: A[] = [2,5,1,3,4]
Output: -1
方法:该想法基于以下观察:如果元素A[i]出现在索引i 处,那么它必须从索引i – 1或i – 2 移动。这是因为,从i – 2左侧的索引转移到A[i] ,交换次数将超过2 。因此,反向遍历数组,并检查A[i]是否存在于其正确位置。如果发现不是,则检查A[i – 1]和A[i – 2]并相应地更新操作计数。请按照以下步骤解决问题:
- 使用变量(例如i)在索引[N – 1, 0] 上遍历数组A[] 。
- 将正确的索引值存储在一个变量中,比如X as i + 1 。
- 如果A[i]当前不在其正确位置,即A[i]不等于X ,则执行以下步骤:
- 如果A[i – 1] 的值等于X ,则将count增加1并交换A[i]和A[i-1] 。
- 否则,如果A[i – 2] 的值等于X ,则将count增加2并交换A[i – 2]和A[i – 1] 对,然后A[i – 2]和A[i ] 。
- 否则,将count的值更新为-1并退出循环,因为A[i]不能交换超过两次。
- 遍历完数组后,打印count的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count minimum number of
// operations required to obtain an
// increasing array from given array A[]
void minimumOperations(int A[], int n)
{
// Store the required result
int cnt = 0;
// Traverse the array A[]
for (int i = n - 1; i >= 0; i--) {
// If the current element is not
// in its correct position
if (A[i] != (i + 1)) {
// Check if it is present at index i - 1
if (((i - 1) >= 0)
&& A[i - 1] == (i + 1)) {
cnt++;
swap(A[i], A[i - 1]);
}
// Check if it is present at index i-2
else if (((i - 2) >= 0)
&& A[i - 2] == (i + 1)) {
cnt += 2;
A[i - 2] = A[i - 1];
A[i - 1] = A[i];
A[i] = i + 1;
}
// Otherwise, print -1 (Since A[i]
// can not be swapped more than twice)
else {
cout << -1;
return;
}
}
}
// Print the result
cout << cnt;
}
// Driver Code
int main()
{
// Given array
int A[] = {7, 3, 2, 1, 4 };
// Store the size of the array
int n = sizeof(A) / sizeof(A[0]);
minimumOperations(A, n);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
class GFG{
// Function to count minimum number of
// operations required to obtain an
// increasing array from given array A[]
static void minimumOperations(int A[], int n)
{
// Store the required result
int cnt = 0;
// Traverse the array A[]
for(int i = n - 1; i >= 0; i--)
{
// If the current element is not
// in its correct position
if (A[i] != (i + 1))
{
// Check if it is present at index i - 1
if (((i - 1) >= 0) &&
A[i - 1] == (i + 1))
{
cnt++;
int t = A[i];
A[i] = A[i-1];
A[i-1] = t;
}
// Check if it is present at index i-2
else if (((i - 2) >= 0) &&
A[i - 2] == (i + 1))
{
cnt += 2;
A[i - 2] = A[i - 1];
A[i - 1] = A[i];
A[i] = i + 1;
}
// Otherwise, print -1 (Since A[i]
// can not be swapped more than twice)
else
{
System.out.println(-1);
return;
}
}
}
// Print the result
System.out.println(cnt);
}
// Driver code
public static void main(String[] args)
{
// Given array
int A[] = { 7, 3, 2, 1, 4 };
// Store the size of the array
int n = A.length;
minimumOperations(A, n);
}
}
// This code is contributed by souravghosh0416
Python3
# Python 3 program for the above approach
# Function to count minimum number of
# operations required to obtain an
# increasing array from given array A[]
def minimumOperations(A, n):
# Store the required result
cnt = 0
# Traverse the array A[]
for i in range(n - 1, -1, -1):
# If the current element is not
# in its correct position
if (A[i] != (i + 1)):
# Check if it is present at index i - 1
if (((i - 1) >= 0)
and A[i - 1] == (i + 1)):
cnt += 1
A[i], A[i - 1] = A[i - 1], A[i]
# Check if it is present at index i-2
elif (((i - 2) >= 0)
and A[i - 2] == (i + 1)):
cnt += 2
A[i - 2] = A[i - 1]
A[i - 1] = A[i]
A[i] = i + 1
# Otherwise, print -1 (Since A[i]
# can not be swapped more than twice)
else:
print(-1)
return
# Print the result
print(cnt)
# Driver Code
if __name__ == "__main__":
# Given array
A = [7, 3, 2, 1, 4]
# Store the size of the array
n = len(A)
minimumOperations(A, n)
# Thi code is contributed by ukasp.
C#
// C# program for the above approach
using System;
class GFG{
// Function to count minimum number of
// operations required to obtain an
// increasing array from given array A[]
static void minimumOperations(int []A, int n)
{
// Store the required result
int cnt = 0;
// Traverse the array A[]
for(int i = n - 1; i >= 0; i--)
{
// If the current element is not
// in its correct position
if (A[i] != (i + 1))
{
// Check if it is present at index i - 1
if (((i - 1) >= 0) &&
A[i - 1] == (i + 1))
{
cnt++;
int t = A[i];
A[i] = A[i-1];
A[i-1] = t;
}
// Check if it is present at index i-2
else if (((i - 2) >= 0) &&
A[i - 2] == (i + 1))
{
cnt += 2;
A[i - 2] = A[i - 1];
A[i - 1] = A[i];
A[i] = i + 1;
}
// Otherwise, print -1 (Since A[i]
// can not be swapped more than twice)
else
{
Console.WriteLine(-1);
return;
}
}
}
// Print the result
Console.WriteLine(cnt);
}
// Driver code
public static void Main()
{
// Given array
int []A = { 7, 3, 2, 1, 4 };
// Store the size of the array
int n = A.Length;
minimumOperations(A, n);
}
}
// This code is contributed by importantly.
Javascript
-1
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。