Maximum subarray sum after dividing array into subarrays based on the given queries in Java


We are given two integer arrays, one having the elements which are computed and other having split points which are required to split the array for making subset and we have to calculate the sum of each subset in every split and return the maximum subset sum.

Let us understand with example:-

Input − int arr[] = int arr[] = { 9, 4, 5, 6, 7 } int splitPoints[] = { 0, 2, 3, 1 };

Output − Maximum subarray sum after each split [22, 13, 9, 9]

Explanation − Here we are breaking the array according to their split points and obtaining the maximum subset sum after each split

After First split → {9} and {4,5,6,7} >> Maximum subarray sum is- 22

After Second split  → {9}, {4,5} and {6,7} >> Maximum subarray sum is- 13

After Third split  →{9}, {4,5}, {6} and {7} >> Maximum subarray sum is- 9

After Fourth split  →{9}, {4}, {5}, {6} and {7} >> Maximum subarray sum is- 9

Input −int arr[] = int arr[] = { 7, 8, 5, 9, 1 } int splitPoints[] = { 1, 2, 0, 3 };

Output −Maximum subarray sum after each split [15, 115, 10, 9]

Explanation −Here we are breaking the array according to their split points and obtaining the maximum subset sum after each split

After First split  → {7,8} and {5,9,1} >> Maximum subarray sum is 15

After Second split  → {7,8}, {5} and {9,1} >> Maximum subarray sum is 115

After Third split  →{7}, {8}, {5} and {9,1} >> Maximum subarray sum is 10

After Fourth split  →{7}, {8}, {5}, {9} and {1} >> Maximum subarray sum is 9

Approach used in the below program is as follows −

  • We will start with the main() method

    • Input arrays of any given length let’s say, arr[] and splitPoints[]. Calculate their lengths and pass to the method as calculateSubsetSum(arr.length, splitPoints.length, splitPoints, arr).

  • Inside the method calculateSubsetSum()

    • Create an integer array as sum[] and set sum[0] as arr[0].

    • Start loop FOR from i to 1 till length of an array and set sum[i] to sum[i - 1] + arr[i] and set temp[0] to new subSets(0, n - 1, sum[n - 1]).

    • Keep adding t2.add(temp[0]) and t1.add(0)

    • Start loop FOR from i to 0 till length of splitPoints array. Inside the loop set currentSplitPoint to t1.floor(splitPoints[i]) and remove from t2 as t2.remove(temp[currentSplitPoint])

    • Set end as temp[currentSplitPoint].last and temp[currentSplitPoint] as new subSets(currentSplitPoint, splitPoints[i], sum[splitPoints[i]] - (currentSplitPoint == 0 ? 0 : sum[currentSplitPoint - 1]))

    • Add using t2.add(temp[currentSplitPoint]) and temp[splitPoints[i] + 1] = new subSets(splitPoints[i] + 1, end, sum[end] - sum[splitPoints[i]])

    • Add using t2.add(temp[splitPoints[i] + 1]), t1.add(currentSplitPoint) and t1.add(splitPoints[i] + 1)

    • Print t2.first() value.

  • Create a class as class subSets and declare first, last and value as its data members and define default constructor as subSets(int f, int l, int v) and set first to f, last to l and value to v

  • Create a class as utilityComparator that will IMPLEMENTS Comparator<subSets>

    • Create a public method as compare and check IF s2.value not equals to s1.value then return s2.value - s1.value.

    • Check IF s1.first not equals to s2.first then return s2.first - s1.first

Example

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
class utilityComparator implements Comparator<subSets>{
   public int compare(subSets s1, subSets s2){
      if(s2.value != s1.value){
         return s2.value - s1.value;
      }
      if(s1.first != s2.first){
         return s2.first - s1.first;
      }
      return 0;
   }
}
class subSets{
   int first;
   int last;
   int value;
   subSets(int f, int l, int v){
      first = f;
      last = l;
      value = v;
   }
}
public class testClass{
   static void calculateSubsetSum(int n, int k, int splitPoints[], int arr[]){
      int sum[] = new int[n];
      sum[0] = arr[0];
      for (int i = 1; i < n; i++){
         sum[i] = sum[i - 1] + arr[i];
      }
      TreeSet<Integer> t1 = new TreeSet<>();
      TreeSet<subSets> t2 = new TreeSet<>(new utilityComparator());
      subSets temp[] = new subSets[n];
      temp[0] = new subSets(0, n - 1, sum[n - 1]);
      t2.add(temp[0]);
      t1.add(0);
      System.out.println("Maximum subarray sum after each split");
      for (int i = 0; i < k; i++){
         int currentSplitPoint = t1.floor(splitPoints[i]);
         t2.remove(temp[currentSplitPoint]);
         int end = temp[currentSplitPoint].last;
         temp[currentSplitPoint] = new subSets(currentSplitPoint, splitPoints[i], sum[splitPoints[i]] - (currentSplitPoint == 0 ? 0 : sum[currentSplitPoint - 1]));
         t2.add(temp[currentSplitPoint]);
         temp[splitPoints[i] + 1] = new subSets(splitPoints[i] + 1, end, sum[end] -       sum[splitPoints[i]]);
         t2.add(temp[splitPoints[i] + 1]);
         t1.add(currentSplitPoint);
         t1.add(splitPoints[i] + 1);
         System.out.println(t2.first().value);
      }
   }
   public static void main(String[] args){
      int arr[] = { 2, 1, 6, 8, 5, 10, 21, 13};
      int splitPoints[] = { 3, 1, 2, 0, 4, 5 };
      calculateSubsetSum(arr.length, splitPoints.length, splitPoints, arr);
   }
}

Output

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

Maximum subarray sum after each split
49
49
49
49
44
34

Updated on: 05-Nov-2021

180 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements