Open In App

Maximum sum bitonic subarray

Last Updated : 23 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array containing n numbers. The problem is to find the maximum sum bitonic subarray. A bitonic subarray is a subarray in which elements are first increasing and then decreasing. A strictly increasing or strictly decreasing subarray is also considered a bitonic subarray. Time Complexity of O(n) is required.

Examples:

Input : arr[] = {5, 3, 9, 2, 7, 6, 4}
Output : 19
The subarray is {2, 7, 6, 4}.

Input : arr[] = {9, 12, 14, 8, 6, 5, 10, 20}
Output : 54
Recommended Practice

Approach: The problem is closely related to the Maximum Sum Bitonic Subsequence. We create two arrays msis[] and msds[]. msis[i] stores the sum of Increasing subarray ending with arr[i]. msds[i] stores the sum of Decreasing subarray starting from arr[i]. Now, maximum sum bitonic subarray is calculated as max(msis[i]+msds[i]-arr[i]) for each index i of the array.

Implementation:

C++




// C++ implementation to find the
// maximum sum bitonic subarray
#include <bits/stdc++.h>
 
using namespace std;
 
// function to find the maximum sum
// bitonic subarray
int maxSumBitonicSubArr(int arr[], int n)
{
    // 'msis[]' to store the maximum sum increasing subarray
    // up to each index of 'arr' from the beginning
    // 'msds[]' to store the maximum sum decreasing subarray
    // from each index of 'arr' up to the end
    int msis[n], msds[n];
     
    // to store the maximum sum
    // bitonic subarray
    int max_sum = INT_MIN;
     
    // building up the maximum sum increasing subarray
    // for each array index
    msis[0] = arr[0];
    for (int i=1; i<n; i++)
        if (arr[i] > arr[i-1])
            msis[i] = msis[i-1] + arr[i];
        else
            msis[i] = arr[i];   
     
    // building up the maximum sum decreasing subarray
    // for each array index
    msds[n-1] = arr[n-1];
    for (int i=n-2; i>=0; i--)
        if (arr[i] > arr[i+1])
            msds[i] = msds[i+1] + arr[i];
        else
            msds[i] = arr[i];
     
    // for each array index, calculating the maximum sum
    // of bitonic subarray of which it is a part of
    for (int i=0; i<n; i++)           
        // if true , then update 'max' bitonic
        // subarray sum
        if (max_sum < (msis[i] + msds[i] - arr[i]))
            max_sum = msis[i] + msds[i] - arr[i];
     
    // required maximum sum
    return max_sum;
}
 
// Driver program to test above
int main()
{
    int arr[] = {5, 3, 9, 2, 7, 6, 4};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr, n);
    return 0;    
}


Java




// Java implementation to
// find the maximum sum
// bitonic subarray
class GFG
{
 
    // function to find the maximum
    // sum bitonic subarray
    static int maxSumBitonicSubArr(int arr[],
                                   int n)
    {
         
    // 'msis[]' to store the maximum
    // sum increasing subarray up to
    // each index of 'arr' from the
    // beginning 'msds[]' to store
    // the maximum sum decreasing
    // subarray from each index of
    // 'arr' up to the end
    int []msis = new int[n];
    int []msds = new int[n];
     
    // to store the maximum
    // sum bitonic subarray
    int max_sum = Integer.MIN_VALUE;
     
    // building up the maximum
    // sum increasing subarray
    // for each array index
    msis[0] = arr[0];
    for (int i = 1; i < n; i++)
        if (arr[i] > arr[i - 1])
            msis[i] = msis[i - 1] +
                       arr[i];
        else
            msis[i] = arr[i];
     
    // building up the maximum
    // sum decreasing subarray
    // for each array index
    msds[n - 1] = arr[n - 1];
    for (int i = n - 2; i >= 0; i--)
        if (arr[i] > arr[i + 1])
            msds[i] = msds[i + 1] + arr[i];
        else
            msds[i] = arr[i];
     
    // for each array index,
    // calculating the maximum
    // sum of bitonic subarray
    // of which it is a part of
    for (int i = 0; i < n; i++)        
     
        // if true , then update
        // 'max' bitonic subarray sum
        if (max_sum < (msis[i] +
                       msds[i] - arr[i]))
            max_sum = msis[i] +
                      msds[i] - arr[i];
     
    // required maximum sum
    return max_sum;
    }
     
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = {5, 3, 9, 2, 7, 6, 4};
        int n = arr.length;
        System.out.println( "Maximum Sum = " +
                 maxSumBitonicSubArr(arr, n));
    }
}
 
// This code is contributed
// by ChitraNayal


Python 3




# Python 3 implementation
# to find the maximum sum
# bitonic subarray
 
# function to find the
# maximum sum bitonic subarray
def maxSumBitonicSubArr(arr, n):
     
    # 'msis[]' to store the maximum
    # sum increasing subarray up to
    # each index of 'arr' from the
    # beginning 'msds[]' to store
    # the maximum sum decreasing
    # subarray from each index of
    # 'arr' up to the end
    msis = [None] * n
    msds = [None] * n
     
    # to store the maximum
    # sum bitonic subarray
    max_sum = 0
     
    # building up the maximum
    # sum increasing subarray
    # for each array index
    msis[0] = arr[0]
    for i in range(1, n):
        if (arr[i] > arr[i - 1]):
            msis[i] = msis[i - 1] + arr[i]
        else:
            msis[i] = arr[i]
     
    # building up the maximum
    # sum decreasing subarray
    # for each array index
    msds[n - 1] = arr[n - 1]
    for i in range(n - 2, -1, -1):
        if (arr[i] > arr[i + 1]):
            msds[i] = msds[i + 1] + arr[i]
        else:
            msds[i] = arr[i]
     
    # for each array index,
    # calculating the maximum
    # sum of bitonic subarray
    # of which it is a part of
    for i in range(n):   
         
        # if true , then update
        # 'max' bitonic subarray sum
        if (max_sum < (msis[i] +
                       msds[i] - arr[i])):
            max_sum = (msis[i] +
                       msds[i] - arr[i])
     
    # required maximum sum
    return max_sum
 
# Driver Code
arr = [5, 3, 9, 2, 7, 6, 4];
n = len(arr)
print("Maximum Sum = "+
       str(maxSumBitonicSubArr(arr, n)))
        
# This code is contributed
# by ChitraNayal


C#




// C# implementation to find
// the maximum sum bitonic subarray
using System;
 
class GFG
{
 
    // function to find the maximum
    // sum bitonic subarray
    static int maxSumBitonicSubArr(int[] arr,
                                   int n)
    {
    // 'msis[]' to store the maximum
    // sum increasing subarray up to
    // each index of 'arr' from the
    // beginning 'msds[]' to store
    // the maximum sum decreasing
    // subarray from each index of
    // 'arr' up to the end
    int []msis = new int[n];
    int []msds = new int[n];
     
    // to store the maximum
    // sum bitonic subarray
    int max_sum = int.MinValue;
     
    // building up the maximum
    // sum increasing subarray
    // for each array index
    msis[0] = arr[0];
    for (int i = 1; i < n; i++)
        if (arr[i] > arr[i - 1])
            msis[i] = msis[i - 1] +
                       arr[i];
        else
            msis[i] = arr[i];
     
    // building up the maximum
    // sum decreasing subarray
    // for each array index
    msds[n - 1] = arr[n - 1];
    for (int i = n - 2; i >= 0; i--)
        if (arr[i] > arr[i + 1])
            msds[i] = msds[i + 1] +
                       arr[i];
        else
            msds[i] = arr[i];
     
    // for each array index, calculating
    // the maximum sum of bitonic subarray
    // of which it is a part of
    for (int i = 0; i < n; i++)   
     
        // if true , then update
        // 'max' bitonic subarray sum
        if (max_sum < (msis[i] +
                       msds[i] - arr[i]))
            max_sum = msis[i] +
                      msds[i] - arr[i];
     
    // required maximum sum
    return max_sum;
    }
     
    // Driver Code
    public static void Main()
    {
        int[] arr = {5, 3, 9, 2, 7, 6, 4};
        int n = arr.Length;
        Console.Write("Maximum Sum = " +
           maxSumBitonicSubArr(arr, n));
    }
}
 
// This code is contributed
// by ChitraNayal


PHP




<?php
// PHP implementation to find the
// maximum sum bitonic subarray
 
// function to find the maximum sum
// bitonic subarray
function maxSumBitonicSubArr($arr, $n)
{
    // 'msis[]' to store the maximum
    // sum increasing subarray up to
    // each index of 'arr' from the
    // beginning 'msds[]' to store
    // the maximum sum decreasing
    // subarray from each index of
    // 'arr' up to the end
    $msis = array();
    $msds = array();
     
    // to store the maximum
    // sum bitonic subarray
    $max_sum = PHP_INT_MIN;
     
    // building up the maximum
    // sum increasing subarray
    // for each array index
    $msis[0] = $arr[0];
    for ($i = 1; $i < $n; $i++)
        if ($arr[$i] > $arr[$i - 1])
            $msis[$i] = $msis[$i - 1] +
                              $arr[$i];
        else
            $msis[$i] = $arr[$i];
     
    // building up the maximum
    // sum decreasing subarray
    // for each array index
    $msds[$n - 1] = $arr[$n - 1];
    for ($i = $n - 2; $i >= 0; $i--)
        if ($arr[$i] > $arr[$i + 1])
            $msds[$i] = $msds[$i + 1] +
                              $arr[$i];
        else
            $msds[$i] = $arr[$i];
     
    // for each array index,
    // calculating the maximum sum
    // of bitonic subarray of which
    // it is a part of
    for ($i = 0; $i < $n; $i++)    
        // if true , then update
        // 'max' bitonic subarray sum
        if ($max_sum < ($msis[$i] +
                        $msds[$i] - $arr[$i]))
            $max_sum = $msis[$i] +
                       $msds[$i] - $arr[$i];
     
    // required maximum sum
    return $max_sum;
}
 
// Driver Code
$arr = array(5, 3, 9,
             2, 7, 6, 4);
$n = sizeof($arr);
echo "Maximum Sum = ",
      maxSumBitonicSubArr($arr, $n);
 
// This code is contributed by ajit
?>


Javascript




<script>
 
    // Javascript implementation to find
    // the maximum sum bitonic subarray
     
    // function to find the maximum
    // sum bitonic subarray
    function maxSumBitonicSubArr(arr, n)
    {
      // 'msis[]' to store the maximum
      // sum increasing subarray up to
      // each index of 'arr' from the
      // beginning 'msds[]' to store
      // the maximum sum decreasing
      // subarray from each index of
      // 'arr' up to the end
      let msis = new Array(n);
      msis.fill(0);
      let msds = new Array(n);
      msds.fill(0);
         
      // to store the maximum
      // sum bitonic subarray
      let max_sum = Number.MIN_VALUE;
 
      // building up the maximum
      // sum increasing subarray
      // for each array index
      msis[0] = arr[0];
      for (let i = 1; i < n; i++)
          if (arr[i] > arr[i - 1])
              msis[i] = msis[i - 1] + arr[i];
          else
              msis[i] = arr[i];
 
      // building up the maximum
      // sum decreasing subarray
      // for each array index
      msds[n - 1] = arr[n - 1];
      for (let i = n - 2; i >= 0; i--)
          if (arr[i] > arr[i + 1])
              msds[i] = msds[i + 1] + arr[i];
          else
              msds[i] = arr[i];
 
      // for each array index, calculating
      // the maximum sum of bitonic subarray
      // of which it is a part of
      for (let i = 0; i < n; i++)   
 
          // if true , then update
          // 'max' bitonic subarray sum
          if (max_sum < (msis[i] + msds[i] - arr[i]))
              max_sum = msis[i] + msds[i] - arr[i];
 
      // required maximum sum
      return max_sum;
    }
     
    let arr = [5, 3, 9, 2, 7, 6, 4];
    let n = arr.length;
    document.write("Maximum Sum = "
    + maxSumBitonicSubArr(arr, n));
     
</script>


Output

Maximum Sum = 19

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

Space optimized solution: It can be solved with constant memory. Indeed, since we are looking for contiguous subarrays, we can separate the initial array into bitonic chunks and compare their sums.

Implementation:

C++




// C++ implementation to find the
// maximum sum bitonic subarray
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the maximum sum bitonic
// subarray.
int maxSumBitonicSubArr(int arr[], int n)
{
    // to store the maximum sum
    // bitonic subarray
    int max_sum = INT_MIN;
 
    int i = 0;
    while (i < n) {
 
        // Find the longest increasing subarray
        // starting at i.
        int j = i;
        while (j+1 < n && arr[j] < arr[j+1])
            j++;
 
        // Now we know that a[i..j] is an
        // increasing subarray. Remove non-
        // positive elements from the left
        // side as much as possible.
        while (i < j && arr[i] <= 0)
            i++;
 
        // Find the longest decreasing subarray
        // starting at j.
        int k = j;
        while (k+1 < n && arr[k] > arr[k+1])
            k++;
 
        // Now we know that a[j..k] is a
        // decreasing subarray. Remove non-
        // positive elements from the right
        // side as much as possible.
        // last is needed to keep the last
        // seen element.
        int last = k;
        while (k > j && arr[k] <= 0)
            k--;
 
 
        // Compute the max sum of the
        // increasing part.
        int sum_inc =
               accumulate(arr+i, arr+j+1, 0);
 
        // Compute the max sum of the
        // decreasing part.
        int sum_dec =
               accumulate(arr+j, arr+k+1, 0);
 
        // The overall max sum is the sum of
        // both parts minus the peak element,
        // because it was counted twice.
        int sum_all = sum_inc + sum_dec - arr[j];
 
        max_sum = max({max_sum, sum_inc,
                       sum_dec, sum_all});
 
        // If the next element is equal to the
        // current, i.e. arr[i+1] == arr[i],
        // last == i.
        // To ensure the algorithm has progress,
        // get the max of last and i+1.
        i = max(last, i+1);
    }
 
    // required maximum sum
    return max_sum;
}
 
// Driver program to test above
int main()
{
    // The example from the article, the
    // answer is 19.
    int arr[] = {5, 3, 9, 2, 7, 6, 4};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr, n)
         << endl;
 
    // Always increasing, the answer is 15.
    int arr2[] = {1, 2, 3, 4, 5};
    int n2 = sizeof(arr2) / sizeof(arr2[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr2, n2)
         << endl;
 
    // Always decreasing, the answer is 15.
    int arr3[] = {5, 4, 3, 2, 1};
    int n3 = sizeof(arr3) / sizeof(arr3[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr3, n3)
         << endl;
 
    // All are equal, the answer is 5.
    int arr4[] = {5, 5, 5, 5};
    int n4 = sizeof(arr4) / sizeof(arr4[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr4, n4)
         << endl;
 
    // The whole array is bitonic, but the answer is 7.
    int arr5[] = {-1, 0, 1, 2, 3, 1, 0, -1, -10};
    int n5 = sizeof(arr5) / sizeof(arr5[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr5, n5)
         << endl;
 
    // The answer is 4 (the tail).
    int arr6[] = {-1, 0, 1, 2, 0, -1, -2, 0, 1, 3};
    int n6 = sizeof(arr6) / sizeof(arr6[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr6, n6)
         << endl;
 
    return 0;
}


Java




// Java implementation to find the
// maximum sum bitonic subarray
import java.util.*;
 
class GFG{
     
static int find_partial_sum(int arr[],
                            int start,
                            int end)
{
    int sum = 0;
    for(int i = start; i < end; i++)
        sum += arr[i];
         
    return sum;
}
 
// Function to find the maximum sum bitonic
// subarray.
static int maxSumBitonicSubArr(int arr[], int n)
{
     
    // To store the maximum sum
    // bitonic subarray
    int max_sum = -1000000;
 
    int i = 0;
    while (i < n)
    {
         
        // Find the longest increasing
        // subarray starting at i.
        int j = i;
        while (j + 1 < n && arr[j] < arr[j + 1])
            j++;
 
        // Now we know that a[i..j] is an
        // increasing subarray. Remove non-
        // positive elements from the left
        // side as much as possible.
        while (i < j && arr[i] <= 0)
            i++;
 
        // Find the longest decreasing subarray
        // starting at j.
        int k = j;
        while (k + 1 < n && arr[k] > arr[k + 1])
            k++;
 
        // Now we know that a[j..k] is a
        // decreasing subarray. Remove non-
        // positive elements from the right
        // side as much as possible.
        // last is needed to keep the last
        // seen element.
        int last = k;
        while (k > j && arr[k] <= 0)
            k--;
 
        // Compute the max sum of the
        // increasing part.
        int sum_inc = find_partial_sum(arr, i,
                                       j + 1);
 
        // Compute the max sum of the
        // decreasing part.
        int sum_dec = find_partial_sum(arr, j,
                                       k + 1);
 
        // The overall max sum is the sum of
        // both parts minus the peak element,
        // because it was counted twice.
        int sum_all = sum_inc + sum_dec - arr[j];
 
        max_sum = Math.max(Math.max(max_sum, sum_inc),
                           Math.max(sum_dec, sum_all));
 
        // If the next element is equal to the
        // current, i.e. arr[i+1] == arr[i],
        // last == i.
        // To ensure the algorithm has progress,
        // get the max of last and i+1.
        i = Math.max(last, i + 1);
    }
     
    // Required maximum sum
    return max_sum;
}
 
// Driver code
public static void main(String args[])
{
     
    // The example from the article, the
    // answer is 19.
    int arr[] = { 5, 3, 9, 2, 7, 6, 4 };
    int n = arr.length;
    System.out.println("Maximum sum = " +
           maxSumBitonicSubArr(arr, n));
     
    // Always increasing, the answer is 15.
    int arr2[] = { 1, 2, 3, 4, 5 };
    int n2 = arr2.length;
    System.out.println("Maximum sum = " +
           maxSumBitonicSubArr(arr2, n2));
 
    // Always decreasing, the answer is 15.
    int arr3[] = { 5, 4, 3, 2, 1 };
    int n3 = arr3.length;
    System.out.println("Maximum sum = " +
           maxSumBitonicSubArr(arr3, n3));
 
    // All are equal, the answer is 5.
    int arr4[] = { 5, 5, 5, 5 };
    int n4 = arr4.length;
    System.out.println("Maximum sum = " +
           maxSumBitonicSubArr(arr4, n4));
 
    // The whole array is bitonic,
    // but the answer is 7.
    int arr5[] = { -1, 0, 1, 2, 3,
                    1, 0, -1, -10 };
    int n5 = arr5.length;
    System.out.println("Maximum sum = " +
           maxSumBitonicSubArr(arr5, n5));
 
    // The answer is 4 (the tail).
    int arr6[] = { -1, 0, 1, 2, 0,
                   -1, -2, 0, 1, 3 };
    int n6 = arr6.length;
    System.out.println("Maximum sum = " +
            maxSumBitonicSubArr(arr6, n6));
}
}
 
// This code is contributed by amreshkumar3


Python3




# Python3 implementation to find the
# maximum sum bitonic subarray
 
# Function to find the maximum sum bitonic
# subarray.
def maxSumBitonicSubArr(arr, n):
     
    # to store the maximum sum
    # bitonic subarray
    max_sum = -10**9
 
    i = 0
    while (i < n):
 
        # Find the longest increasing subarray
        # starting at i.
        j = i
        while (j + 1 < n and arr[j] < arr[j + 1]):
            j += 1
 
        # Now we know that a[i..j] is an
        # increasing subarray. Remove non-
        # positive elements from the left
        # side as much as possible.
        while (i < j and arr[i] <= 0):
            i += 1
 
        # Find the longest decreasing subarray
        # starting at j.
        k = j
        while (k + 1 < n and arr[k] > arr[k + 1]):
            k += 1
 
        # Now we know that a[j..k] is a
        # decreasing subarray. Remove non-
        # positive elements from the right
        # side as much as possible.
        # last is needed to keep the last
        # seen element.
        last = k
        while (k > j and arr[k] <= 0):
            k -= 1
 
        # Compute the max sum of the
        # increasing part.
        nn = arr[i:j + 1]
        sum_inc = sum(nn)
 
        # Compute the max sum of the
        # decreasing part.
        nn = arr[j:k + 1]
        sum_dec = sum(nn)
 
        # The overall max sum is the sum of
        # both parts minus the peak element,
        # because it was counted twice.
        sum_all = sum_inc + sum_dec - arr[j]
 
        max_sum = max([max_sum, sum_inc,
                       sum_dec, sum_all])
 
        # If the next element is equal to the
        # current, i.e. arr[i+1] == arr[i],
        # last == i.
        # To ensure the algorithm has progress,
        # get the max of last and i+1.
        i = max(last, i + 1)
 
    # required maximum sum
    return max_sum
 
# Driver Code
 
# The example from the article, the
# answer is 19.
arr = [5, 3, 9, 2, 7, 6, 4]
n = len(arr)
print("Maximum Sum = ",
       maxSumBitonicSubArr(arr, n))
        
# Always increasing, the answer is 15.
arr2 = [1, 2, 3, 4, 5]
n2 = len(arr2)
print("Maximum Sum = ",
       maxSumBitonicSubArr(arr2, n2))
 
# Always decreasing, the answer is 15.
arr3 = [5, 4, 3, 2, 1]
n3 = len(arr3)
print("Maximum Sum = ",
       maxSumBitonicSubArr(arr3, n3))
 
# All are equal, the answer is 5.
arr4 = [5, 5, 5, 5]
n4 = len(arr4)
print("Maximum Sum = ",
       maxSumBitonicSubArr(arr4, n4))
 
# The whole array is bitonic,
# but the answer is 7.
arr5 = [-1, 0, 1, 2, 3, 1, 0, -1, -10]
n5 = len(arr5)
print("Maximum Sum = ",
       maxSumBitonicSubArr(arr5, n5))
 
# The answer is 4 (the tail).
arr6 = [-1, 0, 1, 2, 0, -1, -2, 0, 1, 3]
n6 = len(arr6)
print("Maximum Sum = ",
       maxSumBitonicSubArr(arr6, n6))
 
# This code is contributed by Mohit Kumar


C#




// C# implementation to find the
// maximum sum bitonic subarray
using System;
 
class GFG{
     
static int find_partial_sum(int []arr,
                            int start,
                            int end)
{
    int sum = 0;
    for(int i = start; i < end; i++)
        sum += arr[i];
         
    return sum;
}
 
// Function to find the maximum sum bitonic
// subarray.
static int maxSumBitonicSubArr(int []arr, int n)
{
     
    // To store the maximum sum
    // bitonic subarray
    int max_sum = -1000000;
 
    int i = 0;
    while (i < n)
    {
         
        // Find the longest increasing subarray
        // starting at i.
        int j = i;
        while (j + 1 < n && arr[j] < arr[j + 1])
            j++;
 
        // Now we know that a[i..j] is an
        // increasing subarray. Remove non-
        // positive elements from the left
        // side as much as possible.
        while (i < j && arr[i] <= 0)
            i++;
 
        // Find the longest decreasing subarray
        // starting at j.
        int k = j;
        while (k + 1 < n && arr[k] > arr[k + 1])
            k++;
 
        // Now we know that a[j..k] is a
        // decreasing subarray. Remove non-
        // positive elements from the right
        // side as much as possible.
        // last is needed to keep the last
        // seen element.
        int last = k;
        while (k > j && arr[k] <= 0)
            k--;
 
        // Compute the max sum of the
        // increasing part.
        int sum_inc = find_partial_sum(arr, i,
                                       j + 1);
 
        // Compute the max sum of the
        // decreasing part.
        int sum_dec = find_partial_sum(arr, j,
                                       k + 1);
 
        // The overall max sum is the sum of
        // both parts minus the peak element,
        // because it was counted twice.
        int sum_all = sum_inc + sum_dec - arr[j];
 
        max_sum = Math.Max(Math.Max(max_sum, sum_inc),
                           Math.Max(sum_dec, sum_all));
 
        // If the next element is equal to the
        // current, i.e. arr[i+1] == arr[i],
        // last == i.
        // To ensure the algorithm has progress,
        // get the max of last and i+1.
        i = Math.Max(last, i + 1);
    }
 
    // Required maximum sum
    return max_sum;
}
 
// Driver code
public static void Main()
{
     
    // The example from the article, the
    // answer is 19.
    int []arr = { 5, 3, 9, 2, 7, 6, 4 };
    int n = arr.Length;
    Console.WriteLine("Maximum sum = " +
            maxSumBitonicSubArr(arr, n));
 
    // Always increasing, the answer is 15.
    int []arr2 = { 1, 2, 3, 4, 5 };
    int n2 = arr2.Length;
    Console.WriteLine("Maximum sum = " +
            maxSumBitonicSubArr(arr2, n2));
 
    // Always decreasing, the answer is 15.
    int []arr3 = { 5, 4, 3, 2, 1 };
    int n3 = arr3.Length;
    Console.WriteLine("Maximum sum = " +
            maxSumBitonicSubArr(arr3, n3));
 
    // All are equal, the answer is 5.
    int []arr4 = { 5, 5, 5, 5 };
    int n4 = arr4.Length;
    Console.WriteLine("Maximum sum = " +
            maxSumBitonicSubArr(arr4, n4));
 
    // The whole array is bitonic,
    // but the answer is 7.
    int []arr5 = { -1, 0, 1, 2, 3,
                    1, 0, -1, -10 };
    int n5 = arr5.Length;
    Console.WriteLine("Maximum sum = " +
            maxSumBitonicSubArr(arr5, n5));
 
    // The answer is 4 (the tail).
    int []arr6 = { -1, 0, 1, 2, 0,
                   -1, -2, 0, 1, 3};
    int n6 = arr6.Length;
    Console.WriteLine("Maximum sum = " +
            maxSumBitonicSubArr(arr6, n6));
}
}
 
// This code is contributed by amreshkumar3


Javascript




<script>
// Javascript implementation to find the
// maximum sum bitonic subarray
     
    function find_partial_sum(arr,start,end)
    {
        let sum = 0;
    for(let i = start; i < end; i++)
        sum += arr[i];
          
    return sum;
    }
 
// Function to find the maximum sum bitonic
// subarray.
function maxSumBitonicSubArr(arr,n)
{
    // To store the maximum sum
    // bitonic subarray
    let max_sum = -1000000;
  
    let i = 0;
    while (i < n)
    {
          
        // Find the longest increasing
        // subarray starting at i.
        let j = i;
        while (j + 1 < n && arr[j] < arr[j + 1])
            j++;
  
        // Now we know that a[i..j] is an
        // increasing subarray. Remove non-
        // positive elements from the left
        // side as much as possible.
        while (i < j && arr[i] <= 0)
            i++;
  
        // Find the longest decreasing subarray
        // starting at j.
        let k = j;
        while (k + 1 < n && arr[k] > arr[k + 1])
            k++;
  
        // Now we know that a[j..k] is a
        // decreasing subarray. Remove non-
        // positive elements from the right
        // side as much as possible.
        // last is needed to keep the last
        // seen element.
        let last = k;
        while (k > j && arr[k] <= 0)
            k--;
  
        // Compute the max sum of the
        // increasing part.
        let sum_inc = find_partial_sum(arr, i,
                                       j + 1);
  
        // Compute the max sum of the
        // decreasing part.
        let sum_dec = find_partial_sum(arr, j,
                                       k + 1);
  
        // The overall max sum is the sum of
        // both parts minus the peak element,
        // because it was counted twice.
        let sum_all = sum_inc + sum_dec - arr[j];
  
        max_sum = Math.max(Math.max(max_sum, sum_inc),
                           Math.max(sum_dec, sum_all));
  
        // If the next element is equal to the
        // current, i.e. arr[i+1] == arr[i],
        // last == i.
        // To ensure the algorithm has progress,
        // get the max of last and i+1.
        i = Math.max(last, i + 1);
    }
      
    // Required maximum sum
    return max_sum;
}
 
// The example from the article, the
// answer is 19.
let arr = [ 5, 3, 9, 2, 7, 6, 4 ];
let n = arr.length;
document.write("Maximum sum = " +
                   maxSumBitonicSubArr(arr, n)+"<br>");
 
// Always increasing, the answer is 15.
let arr2 = [ 1, 2, 3, 4, 5 ];
let n2 = arr2.length;
document.write("Maximum sum = " +
                   maxSumBitonicSubArr(arr2, n2)+"<br>");
 
// Always decreasing, the answer is 15.
let arr3 = [ 5, 4, 3, 2, 1 ];
let n3 = arr3.length;
document.write("Maximum sum = " +
                   maxSumBitonicSubArr(arr3, n3)+"<br>");
 
// All are equal, the answer is 5.
let arr4 = [ 5, 5, 5, 5 ];
let n4 = arr4.length;
document.write("Maximum sum = " +
                   maxSumBitonicSubArr(arr4, n4)+"<br>");
 
// The whole array is bitonic,
// but the answer is 7.
let arr5 = [ -1, 0, 1, 2, 3,
              1, 0, -1, -10 ];
let n5 = arr5.length;
document.write("Maximum sum = " +
                   maxSumBitonicSubArr(arr5, n5)+"<br>");
 
// The answer is 4 (the tail).
let arr6 = [ -1, 0, 1, 2, 0,
              -1, -2, 0, 1, 3 ];
let n6 = arr6.length;
document.write("Maximum sum = " +
                   maxSumBitonicSubArr(arr6, n6)+"<br>");
 
 
// This code is contributed by patel2127
</script>


Output

Maximum Sum = 19
Maximum Sum = 15
Maximum Sum = 15
Maximum Sum = 5
Maximum Sum = 7
Maximum Sum = 4

Time Complexity: The algorithm uses a single while loop to iterate through the array and nested loops to find the increasing and decreasing subarrays, so the time complexity is O(n).

Space Complexity: The algorithm uses constant extra space, so the space complexity is O(1).

Thanks to Andrey Khayrutdinov for suggesting this solution.
 



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

Similar Reads