给定一个大小为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)
高效的方法:上述方法有许多重叠的子问题。因此,可以使用动态规划来优化上述方法。请按照以下步骤解决问题:
- 维护一个二维数组table[][]来存储计算结果。
- 使用较小的子问题的结果应用递归来解决问题。
- 如果arr1[i] < arr2[j] ,则返回 1 + minOperations(arr1, arr2, i + 1, j – 1, table)
- 否则,要么将数组的第 i 个元素移到末尾,要么将数组的第j 个元素移到前面。因此,递推关系为:
table[i][j] = max(minOperations(arr1, arr2, i, j + 1, table), minOperations(arr1, arr2, i + 1, j, table))
- 最后,打印存储在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
蟒蛇3
# 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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live