📌  相关文章
📜  将给定数组转换为Mountain数组所需的最少删除量

📅  最后修改于: 2021-04-23 21:42:46             🧑  作者: Mango

给定一个由N个整数组成的数组arr [] ,任务是找到要使给定数组成为山形数组所需的最少数量的数组元素。

例子:

方法:想法是使用自下而上的动态编程方法解决此问题。请按照以下步骤解决问题:

  1. 如果给定数组的长度小于3,则该数组无法转换为山峰数组。
  2. 否则,遍历数组,对于i元素(0 ,遍历子数组{arr [0],…,arr [i – 1]}中的递增子序列的长度,并将其存储在数组中,说leftIncreasing []
  3. 同样,对于每个i元素(0 ,在子数组{arr [i + 1],…。,arr [N-1]}中找到递增子序列的长度,并将其存储在数组中,说出rightIncreasing []。
  4. 找到满足以下条件的索引i(0
    1. 第一个强制性条件是高峰条件,即leftIncreasing [i]> 0rightIncreasing [i]> 0
    2. 在所有索引中,如果leftIncreasing [i] + rightIncreasing [i]最大,则该索引是山峰阵列的峰值,即X。
  5. 返回结果为N –(X + 1) ,加一以使数组索引变长。

插图:

下面是上述方法的实现:

C++
// C++ program of the above approach
#include 
using namespace std;
  
// Utility function to count array
// elements required to be removed
// to make array a mountain array
int minRemovalsUtil(int arr[], int n)
{
    int result = 0;
    if (n < 3) {
        return -1;
    }
  
    // Stores length of increasing
    // subsequence from [0, i-1]
    int leftIncreasing[n] = {0};
  
    // Stores length of increasing
    // subsequence from [i + 1, n - 1]
    int rightIncreasing[n] = {0};
  
    // Iterate for each position up to
    // N - 1 to find the length of subsequence
    for (int i = 1; i < n; i++) 
    {
        for (int j = 0; j < i; j++) 
        {
  
            // If j is less than i, then
            // i-th position has leftIncreasing[j]
            // + 1 lesser elements including itself
            if (arr[j] < arr[i]) 
            {
  
                // Check if it is the maximum
                // obtained so far
                leftIncreasing[i]
                    = max(leftIncreasing[i],
                          leftIncreasing[j] + 1);
            }
        }
    }
  
    // Search for increasing subsequence from right
    for (int i = n - 2; i >= 0; i--)
    {
        for (int j = n - 1; j > i; j--)
        {
            if (arr[j] < arr[i])
            {
                rightIncreasing[i]
                    = max(rightIncreasing[i],
                               rightIncreasing[j] + 1);
            }
        }
    }
  
    // Find the position following the peak
    // condition and have maximum leftIncreasing[i]
    // + rightIncreasing[i]
    for (int i = 0; i < n; i++)
    {
        if (leftIncreasing[i] != 0
            && rightIncreasing[i] != 0)
        {
            result = max(result,
                         leftIncreasing[i]
                         + rightIncreasing[i]);
        }
    }
    return n - (result + 1);
}
  
// Function to count elements to be
// removed to make array a mountain array
void minRemovals(int arr[], int n)
{
    int ans = minRemovalsUtil(arr, n);
  
    // Print the answer
    cout << ans;
}
  
// Driver Code
int main()
{
  
    // Given array
    int arr[] = { 2, 1, 1, 5, 6, 2, 3, 1 };
    int n = sizeof(arr) / sizeof(arr[0]); 
        
    // Function Call
    minRemovals(arr, n);
    return 0;
}
  
// This code is contributed by Dharanendra L V


Java
// Java program of the above approach
  
import java.io.*;
import java.util.*;
  
class GFG {
  
    // Utility function to count array
    // elements required to be removed
    // to make array a mountain array
    public static int minRemovalsUtil(
        int[] arr)
    {
        int result = 0;
        if (arr.length < 3) {
            return -1;
        }
  
        // Stores length of increasing
        // subsequence from [0, i-1]
        int[] leftIncreasing
            = new int[arr.length];
  
        // Stores length of increasing
        // subsequence from [i + 1, n - 1]
        int[] rightIncreasing = new int[arr.length];
  
        // Iterate for each position up to
        // N - 1 to find the length of subsequence
        for (int i = 1; i < arr.length; i++) {
  
            for (int j = 0; j < i; j++) {
  
                // If j is less than i, then
                // i-th position has leftIncreasing[j]
                // + 1 lesser elements including itself
                if (arr[j] < arr[i]) {
  
                    // Check if it is the maximum
                    // obtained so far
                    leftIncreasing[i]
                        = Math.max(
                            leftIncreasing[i],
                            leftIncreasing[j] + 1);
                }
            }
        }
  
        // Search for increasing subsequence from right
        for (int i = arr.length - 2; i >= 0; i--) {
            for (int j = arr.length - 1; j > i; j--) {
                if (arr[j] < arr[i]) {
                    rightIncreasing[i]
                        = Math.max(rightIncreasing[i],
                                   rightIncreasing[j] + 1);
                }
            }
        }
  
        // Find the position following the peak
        // condition and have maximum leftIncreasing[i]
        // + rightIncreasing[i]
        for (int i = 0; i < arr.length; i++) {
            if (leftIncreasing[i] != 0
                && rightIncreasing[i] != 0) {
                result = Math.max(
                    result, leftIncreasing[i]
                                + rightIncreasing[i]);
            }
        }
  
        return arr.length - (result + 1);
    }
  
    // Function to count elements to be
    // removed to make array a mountain array
    public static void minRemovals(int[] arr)
    {
        int ans = minRemovalsUtil(arr);
  
        // Print the answer
        System.out.println(ans);
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        // Given array
        int[] arr = { 2, 1, 1, 5, 6, 2, 3, 1 };
  
        // Function Call
        minRemovals(arr);
    }
}


Python3
# Python3 program of the above approach
  
# Utility function to count array
# elements required to be removed
# to make array a mountain array
def minRemovalsUtil(arr):
      
    result = 0
      
    if (len(arr) < 3):
        return -1
  
    # Stores length of increasing
    # subsequence from [0, i-1]
    leftIncreasing = [0] * len(arr)
  
    # Stores length of increasing
    # subsequence from [i + 1, n - 1]
    rightIncreasing = [0] * len(arr)
  
    # Iterate for each position up to
    # N - 1 to find the length of subsequence
    for i in range(1, len(arr)):
        for j in range(i):
  
            # If j is less than i, then
            # i-th position has leftIncreasing[j]
            # + 1 lesser elements including itself
            if (arr[j] < arr[i]):
  
                # Check if it is the maximum
                # obtained so far
                leftIncreasing[i] = max(leftIncreasing[i],
                                        leftIncreasing[j] + 1);
                      
    # Search for increasing subsequence from right
    for i in range(len(arr) - 2 , -1, -1):
        j = len(arr) - 1
          
        while j > i:
            if (arr[j] < arr[i]) :
                rightIncreasing[i] = max(rightIncreasing[i],
                                         rightIncreasing[j] + 1)
                                          
            j -= 1
  
    # Find the position following the peak
    # condition and have maximum leftIncreasing[i]
    # + rightIncreasing[i]
    for i in range(len(arr)):
        if (leftIncreasing[i] != 0 and 
           rightIncreasing[i] != 0):
            result = max(result, leftIncreasing[i] +
                                rightIncreasing[i]);
      
    return len(arr) - (result + 1)
  
# Function to count elements to be
# removed to make array a mountain array
def minRemovals(arr):
      
    ans = minRemovalsUtil(arr)
  
    # Print the answer
    print(ans)
  
# Driver Code
if __name__ == "__main__" :
          
    # Given array
    arr = [ 2, 1, 1, 5, 6, 2, 3, 1 ]
  
    # Function Call
    minRemovals(arr)
      
# This code is contributed by AnkThon


C#
// C# program of the above approach
using System;
  
class GFG
{ 
  
    // Utility function to count array
    // elements required to be removed  
    // to make array a mountain array
    public static int minRemovalsUtil(int[] arr)
    {
        int result = 0;
        if (arr.Length < 3) 
        {
            return -1;
        }
  
        // Stores length of increasing
        // subsequence from [0, i-1]
        int[] leftIncreasing
            = new int[arr.Length];
  
        // Stores length of increasing
        // subsequence from [i + 1, n - 1]
        int[] rightIncreasing = new int[arr.Length];
  
        // Iterate for each position up to
        // N - 1 to find the length of subsequence
        for (int i = 1; i < arr.Length; i++)
        {
            for (int j = 0; j < i; j++)
            {
  
                // If j is less than i, then
                // i-th position has leftIncreasing[j]
                // + 1 lesser elements including itself
                if (arr[j] < arr[i]) 
                {
  
                    // Check if it is the maximum
                    // obtained so far
                    leftIncreasing[i]
                        = Math.Max(
                            leftIncreasing[i],
                            leftIncreasing[j] + 1);
                }
            }
        }
  
        // Search for increasing subsequence from right
        for (int i = arr.Length - 2; i >= 0; i--)
        {
            for (int j = arr.Length - 1; j > i; j--) 
            {
                if (arr[j] < arr[i])
                {
                    rightIncreasing[i]
                        = Math.Max(rightIncreasing[i],
                                   rightIncreasing[j] + 1);
                }
            }
        }
  
        // Find the position following the peak
        // condition and have maximum leftIncreasing[i]
        // + rightIncreasing[i]
        for (int i = 0; i < arr.Length; i++)
        {
            if (leftIncreasing[i] != 0
                && rightIncreasing[i] != 0) 
            {
                result = Math.Max(result, leftIncreasing[i]
                                + rightIncreasing[i]);
            }
        }
        return arr.Length - (result + 1);
    }
  
    // Function to count elements to be
    // removed to make array a mountain array
    public static void minRemovals(int[] arr)
    {
        int ans = minRemovalsUtil(arr);
  
        // Print the answer
        Console.WriteLine(ans);
    }
  
    // Driver Code
    public static void Main(String[] args)  
    {
        // Given array
        int[] arr = {2, 1, 1, 5, 6, 2, 3, 1};
  
        // Function Call
        minRemovals(arr);
    }
}
   
// This code is contributed by shikhasingrajput.


输出:
3

时间复杂度: O(N 2 )
辅助空间: O(N)