Open In App

Minimize count of peaks and troughs in given Array after at most one replacement

Last Updated : 29 Jul, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] containing N positive integers, the task is to minimize the total count of peaks (elements having greater value than both the neighbours) and troughs (elements having less value than both the neighbours) by replacing at most one element of the given array with any value.

Note: The first and the last element of the array cannot be a peak or trough as they don’t have two neighbours.

Examples:

Input: arr[] = {2, 7, 4}
Output: 0
Explanation: The count can be made 0 by changing 7 to 3.
The array becomes {2, 3, 4} with no trough and peak.

Input: arr[] = {1, 4, 3, 5, 3, 8}
Output: 1
Explanation: Initially the total count is 4. Go to the index 2 and change its value to 5. 
Now the sequence becomes {1, 4, 5, 5, 3, 8}.
Now only one trough at index 4. 

 

Approach: The given problem can be solved using the Greedy approach. Observe that, any change in ith index affects only the elements at (i+1)th and (i-1)th index. Follow the steps below to solve this problem:

  • Initialize a boolean array mark as false.
  • Also, initialize an integer variable total as 0. It keeps the track of the overall balance of the given sequence.
  • Now iterate over the given array and mark its ith index as true if ith element of the array is either a peak or trough.
  • Initialize another variable ans as total. It keeps the track of the final answer.
  • Now iterate over the array again,
    • Suppose, currently the iteration is at index i,
      • Make the element at the index i equal to i + 1 and update the total balance of the array now.
      • Make the element at the index i equal to i – 1 and update the total balance of the array now.
      • The total balance for the above cases can be achieved easily by creating function isUp() and isDown() that checks there is a peak and trough respectively at a particular index.
      • Also, update the ans variable accordingly.
  • Print the value represented by ans variable.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check up at the index i
bool isUp(int i, int arr[], int N)
{
    return (i > 0 && i < N - 1
            && arr[i] < arr[i - 1]
            && arr[i] < arr[i + 1]);
}
 
// Function to check down at the index i
bool isDown(int i, int arr[], int N)
{
    return (i > 0 && i < N - 1
            && arr[i] > arr[i - 1]
            && arr[i] > arr[i + 1]);
}
 
// Solve function
int solve(int arr[], int N)
{
    // Initializing a boolean array
    bool mark[N] = { 0 };
 
    int total = 0;
 
    // Iterate over the array
    for (int i = 1; i < N - 1; i++) {
 
        // Peak
        if (arr[i] > arr[i + 1]
            && arr[i] > arr[i - 1]) {
            mark[i] = 1;
            total++;
        }
 
        // Trough
        else if (arr[i] < arr[i + 1]
                 && arr[i] < arr[i - 1]) {
            mark[i] = 1;
            total++;
        }
    }
 
    // Initialize ans variable as total
    int ans = total;
    for (int i = 1; i < N - 1; i++) {
 
        // Make arr[i] equal to arr[i - 1]
        int temp = arr[i];
        arr[i] = arr[i - 1];
        ans
 
            = min(
                ans,
                total - mark[i - 1] - mark[i]
                    - mark[i + 1]
                    + isUp(i - 1, arr, N)
                    + isDown(i - 1, arr, N)
                    + isUp(i, arr, N)
                    + isDown(i, arr, N)
                    + isUp(i + 1, arr, N)
                    + isDown(i + 1, arr, N));
 
        // Make arr[i] equal to arr[i + 1]
        arr[i] = arr[i + 1];
        ans
            = min(
                ans,
                total
                    - mark[i - 1] - mark[i]
                    - mark[i + 1]
                    + isUp(i - 1, arr, N)
                    + isDown(i - 1, arr, N)
                    + isUp(i, arr, N)
                    + isDown(i, arr, N)
                    + isUp(i + 1, arr, N)
                    + isDown(i + 1, arr, N));
        arr[i] = temp;
    }
 
    // Return the ans
    return ans;
}
 
// Menu driver code
int main()
{
    // Initializing an array
    int arr[] = { 1, 4, 3, 5, 3, 8 };
 
    // Size of arr
    int N = sizeof(arr) / sizeof(int);
 
    // Calling solve function
    cout << solve(arr, N);
 
    return 0;
}


Java




// Java code for the above approach
import java.util.*;
 
class GFG{
 
  // Function to check up at the index i
  static int isUp(int i, int arr[], int N)
  {
    if (i > 0 && i < N - 1
        && arr[i] < arr[i - 1]
        && arr[i] < arr[i + 1])
    {
      return 1;
    }
    else
      return 0;
  }
 
  // Function to check down at the index i
  static int isDown(int i, int arr[], int N)
  {
    if (i > 0 && i < N - 1
        && arr[i] > arr[i - 1]
        && arr[i] > arr[i + 1])
    {
      return 1;
    }
    else
      return 0;
  }
 
  // Solve function
  static int solve(int arr[], int N)
  {
    // Initializing a boolean array
    int mark[] = new int[N] ;
 
 
    int total = 0;
 
    // Iterate over the array
    for (int i = 1; i < N - 1; i++) {
 
      // Peak
      if (arr[i] > arr[i + 1]
          && arr[i] > arr[i - 1]) {
        mark[i] = 1;
        total++;
      }
 
      // Trough
      else if (arr[i] < arr[i + 1]
               && arr[i] < arr[i - 1]) {
        mark[i] = 1;
        total++;
      }
    }
 
    // Initialize ans variable as total
    int ans = total;
    for (int i = 1; i < N - 1; i++) {
 
      // Make arr[i] equal to arr[i - 1]
      int temp = arr[i];
      arr[i] = arr[i - 1];
      ans
 
        = Math.min(
        ans,
        total - mark[i - 1] - mark[i]
        - mark[i + 1]
        + isUp(i - 1, arr, N)
        + isDown(i - 1, arr, N)
        + isUp(i, arr, N)
        + isDown(i, arr, N)
        + isUp(i + 1, arr, N)
        + isDown(i + 1, arr, N));
 
      // Make arr[i] equal to arr[i + 1]
      arr[i] = arr[i + 1];
      ans
        = Math.min(
        ans,
        total
        - mark[i - 1] - mark[i]
        - mark[i + 1]
        + isUp(i - 1, arr, N)
        + isDown(i - 1, arr, N)
        + isUp(i, arr, N)
        + isDown(i, arr, N)
        + isUp(i + 1, arr, N)
        + isDown(i + 1, arr, N));
      arr[i] = temp;
    }
 
    // Return the ans
    return ans;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
 
    // Initializing an array
    int arr[] = { 1, 4, 3, 5, 3, 8 };
 
    // Size of arr
    int N = arr.length;
 
    // Calling solve function
    System.out.print(solve(arr, N));
  }
}
 
// This code is contributed by sanjoy_62.


Python3




# Python program for the above approach
 
# Function to check up at the index i
def isUp (i, arr, N):
    return (i > 0 and i < N - 1
        and arr[i] < arr[i - 1]
        and arr[i] < arr[i + 1]);
 
# Function to check down at the index i
def isDown (i, arr, N):
    return (i > 0 and i < N - 1
        and arr[i] > arr[i - 1]
        and arr[i] > arr[i + 1]);
 
# Solve function
def solve (arr, N):
    # Initializing a boolean array
    mark = [0] * N
 
    total = 0;
 
    # Iterate over the array
    for i in range(1, N - 1):
 
        # Peak
        if (arr[i] > arr[i + 1] and arr[i] > arr[i - 1]):
            mark[i] = 1;
            total += 1
         
        # Trough
        elif (arr[i] < arr[i + 1]
            and arr[i] < arr[i - 1]):
            mark[i] = 1;
            total += 1
 
    # Initialize ans variable as total
    ans = total;
    for i in range(1, N - 1):
 
        # Make arr[i] equal to arr[i - 1]
        temp = arr[i];
        arr[i] = arr[i - 1];
        ans = min(
            ans,
            total - mark[i - 1] - mark[i]
            - mark[i + 1]
            + isUp(i - 1, arr, N)
            + isDown(i - 1, arr, N)
            + isUp(i, arr, N)
            + isDown(i, arr, N)
            + isUp(i + 1, arr, N)
            + isDown(i + 1, arr, N));
 
        # Make arr[i] equal to arr[i + 1]
        arr[i] = arr[i + 1];
        ans = min(
            ans,
            total
            - mark[i - 1] - mark[i]
            - mark[i + 1]
            + isUp(i - 1, arr, N)
            + isDown(i - 1, arr, N)
            + isUp(i, arr, N)
            + isDown(i, arr, N)
            + isUp(i + 1, arr, N)
            + isDown(i + 1, arr, N));
        arr[i] = temp;
     
    # Return the ans
    return ans;
 
# Menu driver code
 
# Initializing an array
arr = [1, 4, 3, 5, 3, 8];
 
# Size of arr
N = len(arr)
 
# Calling solve function
print(solve(arr, N));
 
# This code is contributed by gfgking


C#




// C# code for the above approach
using System;
 
class GFG {
 
  // Function to check up at the index i
  static int isUp(int i, int []arr, int N)
  {
    if (i > 0 && i < N - 1
        && arr[i] < arr[i - 1]
        && arr[i] < arr[i + 1])
    {
      return 1;
    }
    else
      return 0;
  }
 
  // Function to check down at the index i
  static int isDown(int i, int []arr, int N)
  {
    if (i > 0 && i < N - 1
        && arr[i] > arr[i - 1]
        && arr[i] > arr[i + 1])
    {
      return 1;
    }
    else
      return 0;
  }
 
  // Solve function
  static int solve(int []arr, int N)
  {
    // Initializing a boolean array
    int []mark = new int[N] ;
 
 
    int total = 0;
 
    // Iterate over the array
    for (int i = 1; i < N - 1; i++) {
 
      // Peak
      if (arr[i] > arr[i + 1]
          && arr[i] > arr[i - 1]) {
        mark[i] = 1;
        total++;
      }
 
      // Trough
      else if (arr[i] < arr[i + 1]
               && arr[i] < arr[i - 1]) {
        mark[i] = 1;
        total++;
      }
    }
 
    // Initialize ans variable as total
    int ans = total;
    for (int i = 1; i < N - 1; i++) {
 
      // Make arr[i] equal to arr[i - 1]
      int temp = arr[i];
      arr[i] = arr[i - 1];
      ans
 
        = Math.Min(
        ans,
        total - mark[i - 1] - mark[i]
        - mark[i + 1]
        + isUp(i - 1, arr, N)
        + isDown(i - 1, arr, N)
        + isUp(i, arr, N)
        + isDown(i, arr, N)
        + isUp(i + 1, arr, N)
        + isDown(i + 1, arr, N));
 
      // Make arr[i] equal to arr[i + 1]
      arr[i] = arr[i + 1];
      ans
        = Math.Min(
        ans,
        total
        - mark[i - 1] - mark[i]
        - mark[i + 1]
        + isUp(i - 1, arr, N)
        + isDown(i - 1, arr, N)
        + isUp(i, arr, N)
        + isDown(i, arr, N)
        + isUp(i + 1, arr, N)
        + isDown(i + 1, arr, N));
      arr[i] = temp;
    }
 
    // Return the ans
    return ans;
  }
 
  // Driver Code
  public static void Main()
  {
 
    // Initializing an array
    int []arr = { 1, 4, 3, 5, 3, 8 };
 
    // Size of arr
    int N = arr.Length;
 
    // Calling solve function
    Console.Write(solve(arr, N));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
    // JavaScript program for the above approach
 
    // Function to check up at the index i
    const isUp = (i, arr, N) => {
        return (i > 0 && i < N - 1
            && arr[i] < arr[i - 1]
            && arr[i] < arr[i + 1]);
    }
 
    // Function to check down at the index i
    const isDown = (i, arr, N) => {
        return (i > 0 && i < N - 1
            && arr[i] > arr[i - 1]
            && arr[i] > arr[i + 1]);
    }
 
    // Solve function
    const solve = (arr, N) => {
        // Initializing a boolean array
        let mark = new Array(N).fill(0);
 
        let total = 0;
 
        // Iterate over the array
        for (let i = 1; i < N - 1; i++) {
 
            // Peak
            if (arr[i] > arr[i + 1]
                && arr[i] > arr[i - 1]) {
                mark[i] = 1;
                total++;
            }
 
            // Trough
            else if (arr[i] < arr[i + 1]
                && arr[i] < arr[i - 1]) {
                mark[i] = 1;
                total++;
            }
        }
 
        // Initialize ans variable as total
        let ans = total;
        for (let i = 1; i < N - 1; i++) {
 
            // Make arr[i] equal to arr[i - 1]
            let temp = arr[i];
            arr[i] = arr[i - 1];
            ans = Math.min(
                ans,
                total - mark[i - 1] - mark[i]
                - mark[i + 1]
                + isUp(i - 1, arr, N)
                + isDown(i - 1, arr, N)
                + isUp(i, arr, N)
                + isDown(i, arr, N)
                + isUp(i + 1, arr, N)
                + isDown(i + 1, arr, N));
 
            // Make arr[i] equal to arr[i + 1]
            arr[i] = arr[i + 1];
            ans = Math.min(
                ans,
                total
                - mark[i - 1] - mark[i]
                - mark[i + 1]
                + isUp(i - 1, arr, N)
                + isDown(i - 1, arr, N)
                + isUp(i, arr, N)
                + isDown(i, arr, N)
                + isUp(i + 1, arr, N)
                + isDown(i + 1, arr, N));
            arr[i] = temp;
        }
 
        // Return the ans
        return ans;
    }
 
    // Menu driver code
 
    // Initializing an array
    let arr = [1, 4, 3, 5, 3, 8];
 
    // Size of arr
    let N = arr.length;
 
    // Calling solve function
    document.write(solve(arr, N));
 
// This code is contributed by rakeshsahni
 
</script>


 
 

Output

1

 

Time Complexity: O(N)
Auxiliary Space: O(N)

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads