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.
- Suppose, currently the iteration is at index i,
- Print the value represented by ans variable.
Below is the implementation of the above approach:
// 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 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. |
# 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# 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. |
<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> |
1
Time Complexity: O(N)
Auxiliary Space: O(N)