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

📅  最后修改于: 2021-09-17 07:27:45             🧑  作者: Mango

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

例子:

方法:这个想法是使用自底向上动态规划方法来解决这个问题。请按照以下步骤解决问题:

  1. 如果给定数组的长度小于 3,则该数组无法转换为山形数组。
  2. 否则,遍历数组,对于每个i元素(0 < i < N) ,在子数组{arr[0], …, arr[i – 1]} 中找到递增子序列的长度并将其存储在数组中,说leftIncreasing[]
  3. 同理,求子数组{arr[i+1], …., arr[N-1]}中每i元素(0 < i < N)的递增子序列的长度,并存入数组,说rightIncreasing[]。
  4. 找到满足以下条件的索引i (0 < i < N)
    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.


Javascript


输出:
3

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

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程