Compute maximum of the function efficiently over all sub-arrays

Given an array, arr[] and a function F(i, j). The task is to compute max{F(i, j)} over all sub-arrays [i..j].

The fucntion F() is defined as:

 F(l, r) = \sum_{i = l}^{r - 1} |arr[i] - arr[i+1]|.(-1)^{i-l} 

Examples:

Input : arr[] = { 1, 5, 4, 7 }
Output : 6
Values of F(i, j) for all the sub-arrays:
{ 1, 5 } = |1 – 5| * (1) = 4
{ 1, 5, 4 } = |1 – 5| * (1) + |5 – 4| * (-1) = 3
{ 1, 5, 4, 7 } = |1 – 5| * (1) + |5 – 4| * (-1) + |4 – 7| * (1) = 6
{ 5, 4 } = |5 – 4| * (1) = 1
{ 5, 4, 7 } = |5 – 4| * (1) + |4 – 7| * (-1) = -2
{ 4, 7 } = |4 – 7| * (1) = 3

Max of all the above values = 6.

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

Naive Approach: A naive approach is to traverse over all sub-arrays and calculate the maximum of function F over all the sub-arrays.

Efficient Approach: A better approach is to consider segments in F(l, r) with odd and even l separately. Two different arrays B[] and C[] can be constructed for this purpose such that:

B[i] = |arr[i] - arr[i + 1]| * (-1)i
C[i] = |arr[i] - arr[i + 1]| * (-1)i + 1

Now if we observe closely, we just need to find the maximum sum subarray of the arrays B[] and C[] and final answer of the function will be the maximum among both the arrays.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the above approach
#include <bits/stdc++.h>
  
#define MAX 100005
  
using namespace std;
  
// Function to return maximum sum of a sub-array
int kadaneAlgorithm(const int* ar, int n)
{
    int sum = 0, maxSum = 0;
  
    for (int i = 0; i < n; i++) {
  
        sum += ar[i];
  
        if (sum < 0)
            sum = 0;
  
        maxSum = max(maxSum, sum);
    }
  
    return maxSum;
}
  
// Function to return maximum value of function F
int maxFunction(const int* arr, int n)
{
  
    int b[MAX], c[MAX];
  
    // Compute arrays B[] and C[]
    for (int i = 0; i < n - 1; i++) {
        if (i & 1) {
            b[i] = abs(arr[i + 1] - arr[i]);
            c[i] = -b[i];
        }
        else {
            c[i] = abs(arr[i + 1] - arr[i]);
            b[i] = -c[i];
        }
    }
  
    // Find maximum sum sub-array of both of the
    // arrays and take maximum among them
    int ans = kadaneAlgorithm(b, n - 1);
    ans = max(ans, kadaneAlgorithm(c, n - 1));
  
    return ans;
}
  
// Driver code
int main()
{
    int arr[] = { 1, 5, 4, 7 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << maxFunction(arr, n);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG
{
static int MAX = 100005;
  
  
// Function to return maximum sum of a sub-array 
static int kadaneAlgorithm(int[] ar, int n) 
    int sum = 0, maxSum = 0
  
    for (int i = 0; i < n; i++) 
    
        sum += ar[i]; 
  
        if (sum < 0
            sum = 0
  
        maxSum = Math.max(maxSum, sum); 
    
  
    return maxSum; 
  
// Function to return maximum value 
// of function F 
static int maxFunction(int[] arr, int n) 
  
    int []b = new int[MAX];
    int []c = new int[MAX];
  
    // Compute arrays B[] and C[] 
    for (int i = 0; i < n - 1; i++)
    
        if (i % 2 == 1)
        
            b[i] = Math.abs(arr[i + 1] - arr[i]); 
            c[i] = -b[i]; 
        
        else 
        
            c[i] = Math.abs(arr[i + 1] - arr[i]); 
            b[i] = -c[i]; 
        
    
  
    // Find maximum sum sub-array of both of the 
    // arrays and take maximum among them 
    int ans = kadaneAlgorithm(b, n - 1); 
    ans = Math.max(ans, kadaneAlgorithm(c, n - 1)); 
  
    return ans; 
  
// Driver code 
public static void main(String[] args) 
{
    int arr[] = { 1, 5, 4, 7 }; 
    int n = arr.length; 
    System.out.println(maxFunction(arr, n));
}
}
  
// This code is contributed by PrinciRaj1992 

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the above approach 
MAX = 100005;
  
# Function to return maximum 
# sum of a sub-array 
def kadaneAlgorithm(ar, n) : 
  
    sum = 0; maxSum = 0
  
    for i in range(n) : 
  
        sum += ar[i]; 
  
        if (sum < 0) :
            sum = 0
  
        maxSum = max(maxSum, sum); 
  
    return maxSum; 
  
# Function to return maximum 
# value of function F 
def maxFunction(arr, n) : 
  
    b = [0] * MAX;
    c = [0] * MAX
  
    # Compute arrays B[] and C[] 
    for i in range(n - 1) : 
        if (i & 1) :
            b[i] = abs(arr[i + 1] - arr[i]); 
            c[i] = -b[i]; 
          
        else :
            c[i] = abs(arr[i + 1] - arr[i]); 
            b[i] = -c[i]; 
  
    # Find maximum sum sub-array of both of the 
    # arrays and take maximum among them 
    ans = kadaneAlgorithm(b, n - 1); 
    ans = max(ans, kadaneAlgorithm(c, n - 1)); 
  
    return ans; 
  
# Driver code 
if __name__ == "__main__"
  
    arr = [ 1, 5, 4, 7 ]; 
    n = len(arr)
  
    print(maxFunction(arr, n)); 
  
# This code is contributed by Ryuga

chevron_right


C#

// C# implementation of the approach
using System;

class GFG
{
static int MAX = 100005;

// Function to return maximum sum of a sub-array
static int kadaneAlgorithm(int[] ar, int n)
{
int sum = 0, maxSum = 0;

for (int i = 0; i < n; i++) { sum += ar[i]; if (sum < 0) sum = 0; maxSum = Math.Max(maxSum, sum); } return maxSum; } // Function to return maximum value // of function F static int maxFunction(int[] arr, int n) { int []b = new int[MAX]; int []c = new int[MAX]; // Compute arrays B[] and C[] for (int i = 0; i < n - 1; i++) { if (i % 2 == 1) { b[i] = Math.Abs(arr[i + 1] - arr[i]); c[i] = -b[i]; } else { c[i] = Math.Abs(arr[i + 1] - arr[i]); b[i] = -c[i]; } } // Find maximum sum sub-array of both of the // arrays and take maximum among them int ans = kadaneAlgorithm(b, n - 1); ans = Math.Max(ans, kadaneAlgorithm(c, n - 1)); return ans; } // Driver code public static void Main(String[] args) { int []arr = { 1, 5, 4, 7 }; int n = arr.Length; Console.WriteLine(maxFunction(arr, n)); } } // This code is contributed by PrinciRaj1992 [tabbyending]

Output:

6


My Personal Notes arrow_drop_up

An enthusiastic Java and web developer with a little affinity for tea, cricket, English, etymology, and reading

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01, princiraj1992