📜  最大和双调子阵列

📅  最后修改于: 2021-09-17 07:21:58             🧑  作者: Mango

给定一个包含n 个数字的数组。问题是找到最大和的双音子数组。双调子阵列是其中元素先增加然后减少的子阵列。严格递增或严格递减的子阵列也被认为是双调子阵列。需要 O(n) 的时间复杂度。

例子:

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

方法:该问题与最大和双调子序列密切相关。我们创建了两个数组msis[]msds[] 。 msis[i] 存储以 arr[i] 结尾的递增子数组的总和。 msds[i] 存储从 arr[i] 开始的递减子数组的总和。现在,对于数组的每个索引i ,最大和双音子数组计算为max(msis[i]+msds[i]-arr[i])

C++
// C++ implementation to find the
// maximum sum bitonic subarray
#include 
 
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 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; iJava
// 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
 $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


C++
// C++ implementation to find the
// maximum sum bitonic subarray
#include 
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


输出:

Maximum Sum = 19

时间复杂度: O(n)
辅助空间: O(n)

空间优化解决方案:
它可以通过恒定内存来解决。事实上,由于我们正在寻找连续的子数组,我们可以将初始数组分成双调块并比较它们的总和。

C++

// C++ implementation to find the
// maximum sum bitonic subarray
#include 
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

蟒蛇3

# 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


输出:

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

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程