📌  相关文章
📜  从数组中删除最小元素,使得没有三个连续元素增加或减少

📅  最后修改于: 2022-05-13 01:57:53.019000             🧑  作者: Mango

从数组中删除最小元素,使得没有三个连续元素增加或减少

给定一个包含n 个不同正整数的数组。任务是找到要删除的最小元素数,以使数组中的三个连续元素都不会增加或减少。也就是说,在删除 a i – 1 > a i < a i + 1或 a i – 1 < a i > a i + 1之后。
例子 :

Input : arr[] = {5, 2, 3, 6, 1}
Output : 1
Given arr[] is not in required form 
(2 < 3 < 6). So, after removal of
6 or 3, array will be in required manner.

Input : arr[] = { 4, 2, 6, 3, 10, 1}
Output : 0

请注意,对于 n < 3,输出将为 0,因为不需要删除任何元素。
方法1 O(n 2 ):
如果我们仔细观察,我们可以注意到在从 arr 中删除元素之后,剩下的是 arr 的锯齿形子序列。假设新数组是 arr'。那么我们为到达 arr' 而执行的删除次数就是 arr 的大小 - arr' 的大小。我们的目标是尽量减少这种差异。注意 arr 的大小是固定的,所以我们必须最小化 -arr' 的大小或最大化 arr' 的大小。因此问题被归结为寻找最长之字形子序列。
方法2 O(n):(棘手)
要删除的元素是那些 a i使得
a i-1 > a i > a i+1
a i-1 < a i < a i+1
所以,计算所有那些 a i
这是如何运作的?
让我们定义一个i为,
如果 0 < i < n – 1 和 a i – 1 < a i < a i + 1 ,则达到峰值。
如果 0 < i < n – 1 和 a i – 1 > a i > a i + 1 ,则为谷。
令 P(arr) 和 V(arr) 分别为峰数和谷数。
观察,在任何 zigzag 阵列中,除了端点之外的所有元素都是峰值或谷值,即 n = P(arr) + V(arr) + 2。
现在,我们可以证明任何删除都不会增加任何数组中的峰和谷的总数:
1. 假设我们移除一个既不是峰也不是谷的元素ai

  • 如果 a i是端点,则显然不能形成峰或谷。
  • 如果 a i – 1 < a i < a i + 1 ,则在删除 a i后,元素 a i – 1和 a i + 1将变得相邻。但是由于 a i – 1 < a i + 1 , a i – 1或 a i + 1的状态不会改变,即如果 a i – 1或 a i + 1最初是峰/谷/都不是,那么它将不会改变移除后保持峰值/谷值/两者都不是,因为它们与邻居的比较是相同的。特别是没有形成新的高峰或低谷。
  • 与 a i – 1 > a i > a i + 1的情况类似。

2. 假设我们移除一个峰或谷:

  • 假设我们移除一个峰值,所以 a i – 1 < a i > a i + 1 。现在,a i – 1或 a i + 1可能会变成峰或谷。但是我们可以证明它们不能同时改变,因为要么 a i - 1 < a i + 1 ,这意味着 a i - 1状态永远不会改变,要么 a i - 1 > a i + 1 ,这意味着 a i + 1状态永不改变。因此,最多会形成一个峰或谷,但由于我们移除了一个峰,因此峰/谷的总数不会增加。
  • 当我们移除一个山谷时,同样的事情也会发生,即 a i – 1 > a i < a i + 1

因此任何删除都不会改变 P(arr) + V(arr)。
使用这个论点,我们可以说 arr 的最长 zigzag 子序列的长度最多为 P(arr) + V(arr) + 2。
另一方面,arr 有一个长度为 P(arr) + V(arr) + 2 的锯齿形子序列,即 arr 的峰、谷、端点的序列。可以证明这个子序列是 zigzag(通过尝试一些例子),因此最长的 zigzag 子序列的长度至少为 P(arr) + V(arr) + 2。所以,从前两个参数我们可以说最长的 zigzag子序列的精确长度为 P(arr) + V(arr) + 2。
因此,我们问题的答案是 arr - P(arr) - V(arr) - 2 的大小。
算法 :

1. Initialize count = 0.
2. For each element arr[i] from index i = 1 to n - 2.
   (i) if (arr[i-1]  arr[i+1])
   (ii) increment count by 1.
3. return count.

C++
// C++ program to find minimum
// elements to be removed so
// that array becomes zig-zag.
#include 
using namespace std;
 
int minimumDeletions(int a[],
                     int n)
{
    if (n <= 2)
        return 0;
 
    // If number of element
    // is greater than 2.
    int count = 0;
    for (int i = 0; i < n - 2; i++)
    {
        // If three element are
        // consecutively increasing
        // or decreasing.
        if ((a[i] < a[i + 1] &&
             a[i + 1] < a[i + 2]) ||
            (a[i] > a[i + 1] &&
             a[i + 1] > a[i + 2]))
            count++;
    }
 
    return count;
}
 
// Driver Code
int main()
{
    int a[] = { 5, 2, 3, 6, 1 };
    int n = sizeof(a) / sizeof(a[0]);
 
    cout << minimumDeletions(a, n)
         << endl;
 
    return 0;
}


Java
// Java program to find minimum
// elements to be removed so that
// array becomes zig-zag.
 
class GFG
{
    static int minimumDeletions(int a[],
                                int n)
    {
        if (n <= 2)
            return 0;
     
        // If number of element
        // is greater than 2.
        int count = 0;
        for (int i = 0; i < n - 2; i++)
        {
            // If three element are
            // consecutively increasing
            // or decreasing.
            if ((a[i] < a[i + 1] &&
                 a[i + 1] < a[i + 2]) ||
                (a[i] > a[i + 1] &&
                 a[i + 1] > a[i + 2]))
                count++;
        }
     
        return count;
    }
     
    // Driver Code
    public static void main (String[] args)
    {
        int a[] = { 5, 2, 3, 6, 1 };
        int n = a.length;
     
        System.out.println(minimumDeletions(a, n));
    }
}


Python3
# Python3 program to find minimum
# elements to be removed so that
# array becomes zig-zag.
 
def minimumDeletions(a, n):
 
    if (n <= 2):
        return 0
 
    # If number of element is
    # greater than 2.
    count = 0
    for i in range(n - 2):
     
        # If three element are
        # consecutively increasing
        # or decreasing.
        if ((a[i] < a[i + 1] and
             a[i + 1] < a[i + 2]) or
            (a[i] > a[i + 1] and
             a[i + 1] > a[i + 2])):
            count += 1
             
    return count
 
# Driver Code
a = [ 5, 2, 3, 6, 1 ]
n = len(a)
print(minimumDeletions(a, n))
 
# This code is contributed
# by Anant Agarwal.


C#
// C# program to find minimum
// elements to be removed so
// that array becomes zig-zag.
using System;
 
class GFG
{
    static int minimumDeletions(int []a,
                                int n)
    {
        if (n <= 2)
            return 0;
     
        // If number of element is
        // greater than 2.
        int count = 0;
        for (int i = 0; i < n - 2; i++)
        {
            // If three element are
            // consecutively increasing
            // or decreasing.
            if ((a[i] < a[i + 1] &&
                 a[i + 1] < a[i + 2]) ||
                (a[i] > a[i + 1] &&
                 a[i + 1] > a[i + 2]))
                count++;
        }
     
        return count;
    }
     
    // Driver Code
    public static void Main ()
    {
        int []a = { 5, 2, 3, 6, 1 };
        int n = a.Length;
     
        Console.Write(minimumDeletions(a, n));
    }
}
 
// This code is contributed
// by nitin mittal


PHP
 $a[$i + 1] &&
             $a[$i + 1] > $a[$i + 2]))
            $count++;
    }
 
    return $count;
}
 
// Driver Code
 
{
    $a = array( 5, 2, 3, 6, 1 );
    $n = sizeof($a) / sizeof($a[0]);
 
    echo minimumDeletions($a, $n) ;
 
    return 0;
}
 
// This code is contributed
// by nitin mittal.
?>


Javascript


输出:

1