📌  相关文章
📜  计算对数组进行排序的最前移或最后移出的最小次数

📅  最后修改于: 2021-05-13 23:51:20             🧑  作者: Mango

给定大小为N的数组arr [] ,任务是找到使数组以非降序排序所需的最小移动。

例子:

天真的方法:最简单的方法是检查每个数组元素,对给定数组arr []排序需要多少步。对于每个数组元素,如果它不在其排序位置,则会出现以下可能性:

  • 将当前元素移到最前面。
  • 否则,将当前元素移到末尾。

执行上述操作后,打印使数组排序所需的最少操作数。以下是相同的重复关系:

  • 如果数组arr []与数组brr []相等,则返回0
  • 如果arr [i] < brr [j] ,则运算次数为:
  • 否则,可以通过采用以下最大值的方式来计算操作次数:
    1. recursive_function(arr,brr,i + 1,j)
    2. 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个元素移到前面。因此,递归关系为:
  • 最后,打印存储在表[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)