Maximum Subarray Sum in a given Range in C++

C++Server Side ProgrammingProgramming

We are given with an array of integer elements of any given size. The task is to find the maximum sum which will be calculated by forming the subarrays from the given array within the given range which can be started from any possible index value in an array.

Let us see various input output scenarios for this -

In − int arr[] = { 3, 2, -1, 6, 7, 2 }, int first = 0, int last = 5

Out − Maximum Subarray Sum in a given Range is: 19

Explanation − we are given with an array containing both positive and negative values and a range starting from 0 till 5 i.e. covering all the indexes of an array. So the subarray with maximum sum can be 3 + 6 + 7 + 2 + 2 - 1 i.e. 19.

In − int arr[] = {-2, 1, 3, 4, 8, 9, 23}, int first = 0, int last = 3

Out  − Maximum Subarray Sum in a given Range is: 8

Explanation − we are given with an array containing both positive and negative values and a range starting from 0 till 3 i.e. covering 0 till 3 indexes of an array. So the subarray with maximum sum can be 1 + 3 + 4 i.e. 8.

Approach used in the below program is as follows

  • Construct a structure for a tree that will store max_val, max_temp, total, sub_sum as a member variables and set max_val, max_temp, sum_sum and total as maximum values using default constructor.

  • Create a method of structure as set_node that will form the tree by setting max_val as max(left.max_val, left.total + right.max_val), max_temp as max(right.max_temp, right.total + left.max_temp), total as left.total + right.total and sub_sum as max({left.sub_sum, right.sub_sum, left.max_temp + right.max_val}) then return node.

  • Create a method as build_tree that will be used to construct a tree.

    • Check IF first = last then set total, max_temp, max_val and sub_sum as arr[first] and return.

    • Make a call to the build_tree method as build_tree(node, arr, first, temp, 2 * inx) and build_tree(node, arr, temp + 1, last, 2 * inx + 1) then set node[inx] to set_nodes(node[2 * inx], node[2 * inx + 1])

  • Create a method as create_tree and set temp as (int)(ceil(log2(size))) then make a call to the build_tree() method by passing node object of tree, arr, value 0, size of an array -1 , value 1 as an argument.

  • Create a method to find the maximum subarray sum as maximum_sub(Tree* node, int temp, int temp_2, int temp_3, int temp_4, int inx)

    • Check IF temp greater than temp_4 OR temp_2 less than temp_3then return NULL

    • Check IF temp greater than temp_3 AND temp_2 less than temp_4 then return node[inx]

    • Make a call to the method as left to call the function maximum_sub(node, temp, mid, temp_3, temp_4, 2 * inx) and right to maximum_sub(node, mid + 1, temp_2, temp_3, temp_4, 2 * inx + 1)

    • Set result as set_nodes(left, right)

    • Return result.

  • Create a method as maximum_subarray(Tree* node, int first, int last, int size)

    • Create a call to the method as maximum_sub(node, 0, size - 1, first, last, 1)

    • Return temp.sub_sum

  • In the main() function

    • Declare an array of integer types with positive and negative values and calculate the size of an array.

    • Define the range from first index to last index.

    • Call the function maximum_subarray(node, first, last, size) to calculate the maximum subarray sum in the given range

Example

#include <bits/stdc++.h>
using namespace std;
#define MAX 0x3f3f
struct Tree{
   int max_val;
   int max_temp;
   int total;
   int sub_sum;
   Tree(){
      max_val = max_temp = sub_sum = -MAX;
      total = -MAX;
   }
};

Tree set_nodes(Tree left, Tree right){
   Tree node;
   node.max_val = max(left.max_val, left.total + right.max_val);
   node.max_temp = max(right.max_temp, right.total + left.max_temp);
   node.total = left.total + right.total;
   node.sub_sum = max({left.sub_sum, right.sub_sum, left.max_temp + right.max_val});
   return node;
}
void build_tree(Tree* node, int arr[], int first, int last, int inx){
   if(first == last){
      node[inx].total = arr[first];
      node[inx].max_temp = arr[first];
      node[inx].max_val = arr[first];
      node[inx].sub_sum = arr[first];
      return;
   }
   int temp = (first + last) / 2;
   build_tree(node, arr, first, temp, 2 * inx);
   build_tree(node, arr, temp + 1, last, 2 * inx + 1);
   node[inx] = set_nodes(node[2 * inx], node[2 * inx + 1]);
}
Tree* create_tree(int arr[], int size){
   int temp = (int)(ceil(log2(size)));
   int n = 2 * (int)pow(2, temp) - 1;
   Tree* node = new Tree[n];
   build_tree(node, arr, 0, size - 1, 1);
   return node;
}
Tree maximum_sub(Tree* node, int temp, int temp_2, int temp_3, int temp_4, int inx){
   if(temp > temp_4 || temp_2 < temp_3){
      Tree nullNode;
      return nullNode;
   }
   if(temp >= temp_3 && temp_2 <= temp_4){
      return node[inx];
   }
   int mid = (temp + temp_2) / 2;
   Tree left = maximum_sub(node, temp, mid, temp_3, temp_4, 2 * inx);
   Tree right = maximum_sub(node, mid + 1, temp_2, temp_3, temp_4, 2 * inx + 1);
   Tree result = set_nodes(left, right);
   return result;
}
int maximum_subarray(Tree* node, int first, int last, int size){
   Tree temp = maximum_sub(node, 0, size - 1, first, last, 1);
   return temp.sub_sum;
}
int main(){
   int arr[] = { 3, 2, -1, 6, 7, 2 };
   int size = sizeof(arr) / sizeof(arr[0]);
   Tree* node = create_tree(arr, size);
   int first = 0;
   int last = 5;
   int sub_sum = maximum_subarray(node, first, last, size);
   cout<< "Maximum Subarray Sum in a given Range is: "<< sub_sum;
   return 0;
}

Output

If we run the above code it will generate the following Output

Maximum Subarray Sum in a given Range is: 19
raja
Published on 22-Oct-2021 08:23:39
Advertisements