给定大小为N的数组arr [] ,任务是找到使数组以非降序排序所需的最小移动。
例子:
Input: arr[] = {4, 7, 2, 3, 9}
Output: 2
Explanation:
Perform the following operations:
Step 1: Move the element 3 to the start of the array. Now, arr[] modifies to {3, 4, 7, 2, 9}.
Step 2: Move the element 2 to the start of the array. Now, arr[] modifies to {2, 3, 4, 7, 9}.
Now, the resultant array is sorted.
Therefore, the minimum moves required is 2.
Input: arr[] = {1, 4, 5, 7, 12}
Output: 0
Explanation:
The array is already sorted. Therefore, no moves required.
天真的方法:最简单的方法是检查每个数组元素,对给定数组arr []排序需要多少步。对于每个数组元素,如果它不在其排序位置,则会出现以下可能性:
- 将当前元素移到最前面。
- 否则,将当前元素移到末尾。
执行上述操作后,打印使数组排序所需的最少操作数。以下是相同的重复关系:
- 如果数组arr []与数组brr []相等,则返回0 。
- 如果arr [i] < brr [j] ,则运算次数为:
1 + recursive_function(arr, brr, i + 1, j + 1)
- 否则,可以通过采用以下最大值的方式来计算操作次数:
- recursive_function(arr,brr,i + 1,j)
- recursive_function(arr,brr,i,j + 1)
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function that counts the minimum
// moves required to covert arr[] to brr[]
int minOperations(int arr1[], int arr2[],
int i, int j,
int n)
{
// Base Case
int f = 0;
for (int i = 0; i < n; i++)
{
if (arr1[i] != arr2[i])
f = 1;
break;
}
if (f == 0)
return 0;
if (i >= n || j >= n)
return 0;
// If arr[i] < arr[j]
if (arr1[i] < arr2[j])
// Include the current element
return 1 + minOperations(arr1, arr2,
i + 1, j + 1, n);
// Otherwise, excluding the current element
return max(minOperations(arr1, arr2,
i, j + 1, n),
minOperations(arr1, arr2,
i + 1, j, n));
}
// Function that counts the minimum
// moves required to sort the array
void minOperationsUtil(int arr[], int n)
{
int brr[n];
for (int i = 0; i < n; i++)
brr[i] = arr[i];
sort(brr, brr + n);
int f = 0;
// If both the arrays are equal
for (int i = 0; i < n; i++)
{
if (arr[i] != brr[i])
// No moves required
f = 1;
break;
}
// Otherwise
if (f == 1)
// Print minimum
// operations required
cout << (minOperations(arr, brr,
0, 0, n));
else
cout << "0";
}
// Driver code
int main()
{
int arr[] = {4, 7, 2, 3, 9};
int n = sizeof(arr) / sizeof(arr[0]);
minOperationsUtil(arr, n);
}
// This code is contributed by Chitranayal
Java
// Java program for the above approach
import java.util.*;
import java.io.*;
import java.lang.Math;
class GFG{
// Function that counts the minimum
// moves required to covert arr[] to brr[]
static int minOperations(int arr1[], int arr2[],
int i, int j)
{
// Base Case
if (arr1.equals(arr2))
return 0;
if (i >= arr1.length || j >= arr2.length)
return 0;
// If arr[i] < arr[j]
if (arr1[i] < arr2[j])
// Include the current element
return 1 + minOperations(arr1, arr2,
i + 1, j + 1);
// Otherwise, excluding the current element
return Math.max(minOperations(arr1, arr2,
i, j + 1),
minOperations(arr1, arr2,
i + 1, j));
}
// Function that counts the minimum
// moves required to sort the array
static void minOperationsUtil(int[] arr)
{
int brr[] = new int[arr.length];
for(int i = 0; i < arr.length; i++)
brr[i] = arr[i];
Arrays.sort(brr);
// If both the arrays are equal
if (arr.equals(brr))
// No moves required
System.out.print("0");
// Otherwise
else
// Print minimum operations required
System.out.println(minOperations(arr, brr,
0, 0));
}
// Driver code
public static void main(final String[] args)
{
int arr[] = { 4, 7, 2, 3, 9 };
minOperationsUtil(arr);
}
}
// This code is contributed by bikram2001jha
Python3
# Python3 program for the above approach
# Function that counts the minimum
# moves required to covert arr[] to brr[]
def minOperations(arr1, arr2, i, j):
# Base Case
if arr1 == arr2:
return 0
if i >= len(arr1) or j >= len(arr2):
return 0
# If arr[i] < arr[j]
if arr1[i] < arr2[j]:
# Include the current element
return 1 \
+ minOperations(arr1, arr2, i + 1, j + 1)
# Otherwise, excluding the current element
return max(minOperations(arr1, arr2, i, j + 1),
minOperations(arr1, arr2, i + 1, j))
# Function that counts the minimum
# moves required to sort the array
def minOperationsUtil(arr):
brr = sorted(arr);
# If both the arrays are equal
if(arr == brr):
# No moves required
print("0")
# Otherwise
else:
# Print minimum operations required
print(minOperations(arr, brr, 0, 0))
# Driver Code
arr = [4, 7, 2, 3, 9]
minOperationsUtil(arr)
C#
// C# program for the above approach
using System;
class GFG{
// Function that counts the minimum
// moves required to covert arr[] to brr[]
static int minOperations(int[] arr1, int[] arr2,
int i, int j)
{
// Base Case
if (arr1.Equals(arr2))
return 0;
if (i >= arr1.Length ||
j >= arr2.Length)
return 0;
// If arr[i] < arr[j]
if (arr1[i] < arr2[j])
// Include the current element
return 1 + minOperations(arr1, arr2,
i + 1, j + 1);
// Otherwise, excluding the current element
return Math.Max(minOperations(arr1, arr2,
i, j + 1),
minOperations(arr1, arr2,
i + 1, j));
}
// Function that counts the minimum
// moves required to sort the array
static void minOperationsUtil(int[] arr)
{
int[] brr = new int[arr.Length];
for(int i = 0; i < arr.Length; i++)
brr[i] = arr[i];
Array.Sort(brr);
// If both the arrays are equal
if (arr.Equals(brr))
// No moves required
Console.Write("0");
// Otherwise
else
// Print minimum operations required
Console.WriteLine(minOperations(arr, brr,
0, 0));
}
// Driver code
static void Main()
{
int[] arr = { 4, 7, 2, 3, 9 };
minOperationsUtil(arr);
}
}
// This code is contributed by divyeshrabadiya07
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// Function that counts the minimum
// moves required to covert arr[] to brr[]
int minOperations(int arr1[], int arr2[], int i, int j,
int n, map, int> table)
{
// Base Cases
pair key = {i, j};
if (arr1 == arr2)
return 0;
if (i >= n || j >= n)
return 0;
// If the result is already stored
if (table.find(key) != table.end())
return table[key];
// Compute the result
if (arr1[i] < arr2[j])
return 1 + minOperations(
arr1, arr2, i + 1, j + 1, n, table);
// Store the result
table[key] = max(
minOperations(arr1, arr2, i, j + 1, n, table),
minOperations(arr1, arr2, i + 1, j, n, table));
// Return the result
return table[key];
}
// Function that counts the minimum
// moves required to sort the array
void minOperationsUtil(int arr[], int n)
{
int brr[n];
for(int i = 0; i < n; i++)
brr[i] = arr[i];
sort(brr, brr + n);
if (brr == arr)
cout << 0;
else
{
map, int> table;
cout << n - minOperations(
brr, arr, 0, 0, n, table);
}
}
// Driver code
int main()
{
int arr[] = { 4, 7, 2, 3, 9 };
int n = sizeof(arr) / sizeof(arr[0]);
minOperationsUtil(arr, n);
}
// This code is contributed by grand_master
Python3
# Python3 program for the above approach
# Function to find the minimum number
# of moves required to sort the array
def minOperations(arr1, arr2, i, j, table):
key = (i, j)
# Base Cases
if arr1 == arr2:
return 0
if i >= len(arr1) or j >= len(arr2):
return 0
# If the result is already stored
if key in table:
return table[key]
# Compute the result
if arr1[i] < arr2[j]:
return 1 + minOperations(
arr1, arr2, i + 1,
j + 1, table)
# Store the result
table[key] = max(
minOperations(arr1, arr2, i,
j + 1, table),
minOperations(arr1, arr2, i + 1,
j, table))
# Return the result
return table[key]
# Function to print the minimum
# moves required to sort the array
def minOperationsUtil(arr):
brr = sorted(arr)
table = dict()
# If both the arrays are equal
if brr == arr:
# No moves required
print(0)
# Otherwise
else:
print(len(brr) -
minOperations(brr, arr, 0, 0, table))
# Driver Code
arr = [4, 7, 2, 3, 9]
minOperationsUtil(arr)
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function that counts the minimum
// moves required to covert arr[] to brr[]
static int minOperations(int[] arr1, int[] arr2, int i, int j,
int n, Dictionary, int> table)
{
// Base Cases
Tuple key = new Tuple(i, j);
if (arr1 == arr2)
return 0;
if (i >= n || j >= n)
return 0;
// If the result is already stored
if (table.ContainsKey(key))
return table[key];
// Compute the result
if (arr1[i] < arr2[j])
return 1 + minOperations(
arr1, arr2, i + 1, j + 1, n, table);
// Store the result
table[key] = Math.Max(
minOperations(arr1, arr2, i, j + 1, n, table),
minOperations(arr1, arr2, i + 1, j, n, table));
// Return the result
return table[key];
}
// Function that counts the minimum
// moves required to sort the array
static void minOperationsUtil(int[] arr, int n)
{
int[] brr = new int[n];
for(int i = 0; i < n; i++)
brr[i] = arr[i];
Array.Sort(brr);
if (brr == arr)
Console.Write(0);
else
{
Dictionary, int> table =
new Dictionary, int>();
Console.Write(n - minOperations(brr, arr, 0, 0, n, table));
}
}
// Driver code
static void Main()
{
int[] arr = { 4, 7, 2, 3, 9 };
int n = arr.Length;
minOperationsUtil(arr, n);
}
}
// This code is contributed by divyesh072019
2
时间复杂度: O(2 N )
辅助空间: O(N)
高效的方法:上述方法有许多重叠的子问题。因此,可以使用动态编程来优化上述方法。请按照以下步骤解决问题:
- 维护2D数组表[] []以存储计算的结果。
- 应用较小子问题的结果来递归解决问题。
- 如果arr1 [i]
,则返回1 + minOperations(arr1,arr2,i + 1,j – 1,表) - 否则,可以将数组的第i个元素移到末尾,或者将数组的第j个元素移到前面。因此,递归关系为:
table[i][j] = max(minOperations(arr1, arr2, i, j + 1, table), minOperations(arr1, arr2, i + 1, j, table))
- 最后,打印存储在表[0] [N – 1]中的值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function that counts the minimum
// moves required to covert arr[] to brr[]
int minOperations(int arr1[], int arr2[], int i, int j,
int n, map, int> table)
{
// Base Cases
pair key = {i, j};
if (arr1 == arr2)
return 0;
if (i >= n || j >= n)
return 0;
// If the result is already stored
if (table.find(key) != table.end())
return table[key];
// Compute the result
if (arr1[i] < arr2[j])
return 1 + minOperations(
arr1, arr2, i + 1, j + 1, n, table);
// Store the result
table[key] = max(
minOperations(arr1, arr2, i, j + 1, n, table),
minOperations(arr1, arr2, i + 1, j, n, table));
// Return the result
return table[key];
}
// Function that counts the minimum
// moves required to sort the array
void minOperationsUtil(int arr[], int n)
{
int brr[n];
for(int i = 0; i < n; i++)
brr[i] = arr[i];
sort(brr, brr + n);
if (brr == arr)
cout << 0;
else
{
map, int> table;
cout << n - minOperations(
brr, arr, 0, 0, n, table);
}
}
// Driver code
int main()
{
int arr[] = { 4, 7, 2, 3, 9 };
int n = sizeof(arr) / sizeof(arr[0]);
minOperationsUtil(arr, n);
}
// This code is contributed by grand_master
Python3
# Python3 program for the above approach
# Function to find the minimum number
# of moves required to sort the array
def minOperations(arr1, arr2, i, j, table):
key = (i, j)
# Base Cases
if arr1 == arr2:
return 0
if i >= len(arr1) or j >= len(arr2):
return 0
# If the result is already stored
if key in table:
return table[key]
# Compute the result
if arr1[i] < arr2[j]:
return 1 + minOperations(
arr1, arr2, i + 1,
j + 1, table)
# Store the result
table[key] = max(
minOperations(arr1, arr2, i,
j + 1, table),
minOperations(arr1, arr2, i + 1,
j, table))
# Return the result
return table[key]
# Function to print the minimum
# moves required to sort the array
def minOperationsUtil(arr):
brr = sorted(arr)
table = dict()
# If both the arrays are equal
if brr == arr:
# No moves required
print(0)
# Otherwise
else:
print(len(brr) -
minOperations(brr, arr, 0, 0, table))
# Driver Code
arr = [4, 7, 2, 3, 9]
minOperationsUtil(arr)
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function that counts the minimum
// moves required to covert arr[] to brr[]
static int minOperations(int[] arr1, int[] arr2, int i, int j,
int n, Dictionary, int> table)
{
// Base Cases
Tuple key = new Tuple(i, j);
if (arr1 == arr2)
return 0;
if (i >= n || j >= n)
return 0;
// If the result is already stored
if (table.ContainsKey(key))
return table[key];
// Compute the result
if (arr1[i] < arr2[j])
return 1 + minOperations(
arr1, arr2, i + 1, j + 1, n, table);
// Store the result
table[key] = Math.Max(
minOperations(arr1, arr2, i, j + 1, n, table),
minOperations(arr1, arr2, i + 1, j, n, table));
// Return the result
return table[key];
}
// Function that counts the minimum
// moves required to sort the array
static void minOperationsUtil(int[] arr, int n)
{
int[] brr = new int[n];
for(int i = 0; i < n; i++)
brr[i] = arr[i];
Array.Sort(brr);
if (brr == arr)
Console.Write(0);
else
{
Dictionary, int> table =
new Dictionary, int>();
Console.Write(n - minOperations(brr, arr, 0, 0, n, table));
}
}
// Driver code
static void Main()
{
int[] arr = { 4, 7, 2, 3, 9 };
int n = arr.Length;
minOperationsUtil(arr, n);
}
}
// This code is contributed by divyesh072019
输出:
2
时间复杂度: O(N)
辅助空间: O(N)