Open In App

Print all strings corresponding to elements in a subarray with maximum absolute sum

Last Updated : 14 Sep, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] consisting of N pairs, each consisting of a string and an integer value corresponding to that string. The task is to find the maximum absolute sum subarray and print the strings corresponding to the elements of the subarray.

Examples:

Input: arr[] = {(“geeks”, 4), (“for”, -3), (“geeks”, 2), (“tutorial”, 3), (“program”, -4)}
Output: geeks for geeks tutorial 
Explanation: The maximum absolute sum subarray is {arr[0], .. arr[3]}, having sum 6. Therefore, corresponding strings between these values are “geeks”, “for”, “geeks” and “tutorial”.

Input: arr[]= {(“practice”, -7), (“makes”, 2 ), (“men perfect”, 5)}
Output: practice
Explanation: The maximum absolute sum subarray is {arr[0]}, having sum 7. Therefore, corresponding string is “practice”.

Naive Approach: The simplest approach is to generate all possible subarrays find the maximum sum subarray. Then, print the string corresponding to that subarray. 
Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: The optimal idea is to use Kadane’s Algorithm with some modification in it so that it can handle negative values and choose the maximum between the absolute minimum value and absolute maximum value.

Follow the steps below to solve the problem:

  1. Initialize variables, res = 0, to store the final answer and start = 0, end = 0 to store the starting and ending indices of the required subarray.
  2. Initialize two more variables, say posPrefix and negPrefix, to store the previous positive prefix value and negative prefix value.
  3. Traverse the array arr[]and perform the following
    • If the current element is negative, and if the value of arr[i] + negPrefix > res, then update the value of res, start and end index.
    • If the current element is positive, and if the value of arr[i] + posPrefix > res, then update the value of res, start and end index.
    • Check if adding the current element to negPrefix makes it greater than or equal to 0, then update the start = i + 1 and set negPrefix = 0 otherwise, add the current value to negPrefix.
    • Check if adding the current element to posPrefix makes it lesser than or equal to 0, then update the start = i + 1 and set posPrefix = 0 otherwise, add the current value to posPrefix.
  4. Finally, traverse the array in the range [start, end] and print the corresponding strings.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to print strings corresponding
// to the elements present in the subarray
// with maximum absolute sum
void maximumAbsSum(pair<string, int>* arr,
                   int N)
{
    int start = 0, end = 0, res = 0,
        negIndex = 0, posIndex = 0,
        negPrefix = 0, posPrefix = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++) {
 
        if (arr[i].second < 0) {
 
            // If adding current element
            // to negative
            // prefix makes it > res
            // then update the values
 
            if (res < abs(arr[i].second
                          + negPrefix)) {
 
                res = abs(arr[i].second
                          + negPrefix);
                start = negIndex;
                end = i;
            }
        }
 
        else {
 
            // If adding current element to
            // positive prefix exceeds res
            if (res < abs(arr[i].second
                          + posPrefix)) {
 
                res = abs(arr[i].second
                          + posPrefix);
                start = posIndex;
                end = i;
            }
        }
 
        // Since negPrefix > 0, there is
        // no benefit in adding it to a
        // negative value
        if (negPrefix + arr[i].second > 0) {
 
            negPrefix = 0;
            negIndex = i + 1;
        }
 
        // Since negative + negative
        // generates a larger negative value
        else {
 
            negPrefix += arr[i].second;
        }
 
        // Since positive + positive
        // generates a larger positive number
        if (posPrefix + arr[i].second >= 0) {
 
            posPrefix += arr[i].second;
        }
 
        // Since pos_prefix < 0, there is
        // no benefit in adding it to
        // a positive value
        else {
 
            posPrefix = 0;
            posIndex = i + 1;
        }
    }
 
    // Print the corresponding strings
    for (int i = start; i <= end; i++) {
        cout << arr[i].first << " ";
    }
}
 
// Driver Code
int main()
{
    // Given array
    pair<string, int> arr[] = { { "geeks", 4 },
                                { "for", -3 },
                                { "geeks", 2 },
                                { "tutorial", 3 },
                                { "program", -4 } };
 
    // Size of the array
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function call to print
    // string corresponding to
    // maximum absolute subarray sum
    maximumAbsSum(arr, N);
}


Java




// Java program for the above approach
class GFG
{
    static class pair<E,R>
    {
        E first;
        R second;
        public pair(E first, R second) 
        {
            this.first = first;
            this.second = second;
        }   
    }
   
// Function to print Strings corresponding
// to the elements present in the subarray
// with maximum absolute sum
static void maximumAbsSum(pair<String,Integer> []arr,
                   int N)
{
    int start = 0, end = 0, res = 0,
        negIndex = 0, posIndex = 0,
        negPrefix = 0, posPrefix = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++)
    {
        if (arr[i].second < 0)
        {
 
            // If adding current element
            // to negative
            // prefix makes it > res
            // then update the values
            if (res < Math.abs(arr[i].second
                          + negPrefix)) {
 
                res = Math.abs(arr[i].second
                          + negPrefix);
                start = negIndex;
                end = i;
            }
        }
        else
        {
 
            // If adding current element to
            // positive prefix exceeds res
            if (res < Math.abs(arr[i].second
                          + posPrefix)) {
 
                res = Math.abs(arr[i].second
                          + posPrefix);
                start = posIndex;
                end = i;
            }
        }
 
        // Since negPrefix > 0, there is
        // no benefit in adding it to a
        // negative value
        if (negPrefix + arr[i].second > 0) {
 
            negPrefix = 0;
            negIndex = i + 1;
        }
 
        // Since negative + negative
        // generates a larger negative value
        else {
 
            negPrefix += arr[i].second;
        }
 
        // Since positive + positive
        // generates a larger positive number
        if (posPrefix + arr[i].second >= 0) {
 
            posPrefix += arr[i].second;
        }
 
        // Since pos_prefix < 0, there is
        // no benefit in adding it to
        // a positive value
        else {
 
            posPrefix = 0;
            posIndex = i + 1;
        }
    }
 
    // Print the corresponding Strings
    for (int i = start; i <= end; i++) {
        System.out.print(arr[i].first+ " ");
    }
}
 
// Driver Code
@SuppressWarnings("unchecked")
public static void main(String[] args)
{
    // Given array
    @SuppressWarnings("rawtypes")
    pair arr[] = { new pair( "geeks", 4 ),
            new pair( "for", -3 ),
            new pair( "geeks", 2 ),
            new pair( "tutorial", 3 ),
            new pair( "program", -4 ) };
 
    // Size of the array
    int N = arr.length;
 
    // Function call to print
    // String corresponding to
    // maximum absolute subarray sum
    maximumAbsSum(arr, N);
}
}
 
// This code is contributed by shikhasingrajput


Python3




# Python3 program for the above approach
 
# Function to print strings corresponding
# to the elements present in the subarray
# with maximum absolute sum
def maximumAbsSum(arr, N):
    start, end, res = 0, 0, 0
    negIndex, posIndex = 0, 0
    negPrefix, posPrefix = 0, 0
 
    # Traverse the array
    for i in range(N):
        if (arr[i][1] < 0):
 
            # If adding current element
            # to negative
            # prefix makes it > res
            # then update the values
            if (res < abs(arr[i][1] + negPrefix)):
                res = abs(arr[i][1] + negPrefix)
                start = negIndex
                end = i
        else:
 
            # If adding current element to
            # positive prefix exceeds res
            if (res < abs(arr[i][1] + posPrefix)):
                res = abs(arr[i][1] + posPrefix)
                start = posIndex
                end = i
 
        # Since negPrefix > 0, there is
        # no benefit in adding it to a
        # negative value
        if (negPrefix + arr[i][1] > 0):
            negPrefix = 0
            negIndex = i + 1
             
        # Since negative + negative
        # generates a larger negative value
        else:
            negPrefix += arr[i][1]
 
        # Since positive + positive
        # generates a larger positive number
        if (posPrefix + arr[i][1] >= 0):
            posPrefix += arr[i][1]
 
        # Since pos_prefix < 0, there is
        # no benefit in adding it to
        # a positive value
        else:
            posPrefix = 0
            posIndex = i + 1
 
    # Print the corresponding strings
    for i in range(start, end + 1):
        print(arr[i][0], end = " ")
 
# Driver Code
if __name__ == '__main__':
   
    # Given array
    arr = [ [ "geeks", 4 ],
            [ "for", -3 ],
            [ "geeks", 2 ],
            [ "tutorial", 3 ],
            [ "program", -4 ] ]
 
    # Size of the array
    N = len(arr)
 
    # Function call to print
    # string corresponding to
    # maximum absolute subarray sum
    maximumAbsSum(arr, N)
 
    # This code is contributed by mohit kumar 29.


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG
{
  public class pair
  {
    public string first;
    public int second;
    public pair(string first, int second) 
    {
      this.first = first;
      this.second = second;
    }   
  }
 
  // Function to print Strings corresponding
  // to the elements present in the subarray
  // with maximum absolute sum
  static void maximumAbsSum(pair []arr,
                            int N)
  {
    int start = 0, end = 0, res = 0,
    negIndex = 0, posIndex = 0,
    negPrefix = 0, posPrefix = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++)
    {
      if (arr[i].second < 0)
      {
 
        // If adding current element
        // to negative
        // prefix makes it > res
        // then update the values
        if (res < Math.Abs(arr[i].second
                           + negPrefix)) {
 
          res = Math.Abs(arr[i].second
                         + negPrefix);
          start = negIndex;
          end = i;
        }
      }
      else
      {
 
        // If adding current element to
        // positive prefix exceeds res
        if (res < Math.Abs(arr[i].second
                           + posPrefix)) {
 
          res = Math.Abs(arr[i].second
                         + posPrefix);
          start = posIndex;
          end = i;
        }
      }
 
      // Since negPrefix > 0, there is
      // no benefit in adding it to a
      // negative value
      if (negPrefix + arr[i].second > 0) {
 
        negPrefix = 0;
        negIndex = i + 1;
      }
 
      // Since negative + negative
      // generates a larger negative value
      else {
 
        negPrefix += arr[i].second;
      }
 
      // Since positive + positive
      // generates a larger positive number
      if (posPrefix + arr[i].second >= 0) {
 
        posPrefix += arr[i].second;
      }
 
      // Since pos_prefix < 0, there is
      // no benefit in adding it to
      // a positive value
      else {
 
        posPrefix = 0;
        posIndex = i + 1;
      }
    }
 
    // Print the corresponding Strings
    for (int i = start; i <= end; i++) {
      Console.Write(arr[i].first+ " ");
    }
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
     
    // Given array
    pair []arr = { new pair( "geeks", 4 ),
                  new pair( "for", -3 ),
                  new pair( "geeks", 2 ),
                  new pair( "tutorial", 3 ),
                  new pair( "program", -4 ) };
 
    // Size of the array
    int N = arr.Length;
 
    // Function call to print
    // String corresponding to
    // maximum absolute subarray sum
    maximumAbsSum(arr, N);
  }
}
 
// This code is contributed by Rajput-Ji


Javascript




<script>
// Javascript program for the above approach
 
class pair
{
    constructor(first,second)
    {
        this.first=first;
        this.second=second;
    }
}
 
// Function to print Strings corresponding
// to the elements present in the subarray
// with maximum absolute sum
function maximumAbsSum(arr,N)
{
    let start = 0, end = 0, res = 0,
        negIndex = 0, posIndex = 0,
        negPrefix = 0, posPrefix = 0;
  
    // Traverse the array
    for (let i = 0; i < N; i++)
    {
        if (arr[i].second < 0)
        {
  
            // If adding current element
            // to negative
            // prefix makes it > res
            // then update the values
            if (res < Math.abs(arr[i].second
                          + negPrefix)) {
  
                res = Math.abs(arr[i].second
                          + negPrefix);
                start = negIndex;
                end = i;
            }
        }
        else
        {
  
            // If adding current element to
            // positive prefix exceeds res
            if (res < Math.abs(arr[i].second
                          + posPrefix)) {
  
                res = Math.abs(arr[i].second
                          + posPrefix);
                start = posIndex;
                end = i;
            }
        }
  
        // Since negPrefix > 0, there is
        // no benefit in adding it to a
        // negative value
        if (negPrefix + arr[i].second > 0) {
  
            negPrefix = 0;
            negIndex = i + 1;
        }
  
        // Since negative + negative
        // generates a larger negative value
        else {
  
            negPrefix += arr[i].second;
        }
  
        // Since positive + positive
        // generates a larger positive number
        if (posPrefix + arr[i].second >= 0) {
  
            posPrefix += arr[i].second;
        }
  
        // Since pos_prefix < 0, there is
        // no benefit in adding it to
        // a positive value
        else {
  
            posPrefix = 0;
            posIndex = i + 1;
        }
    }
  
    // Print the corresponding Strings
    for (let i = start; i <= end; i++) {
        document.write(arr[i].first+ " ");
    }
}
 
// Driver Code
// Given array
let arr=[new pair( "geeks", 4 ),
            new pair( "for", -3 ),
            new pair( "geeks", 2 ),
            new pair( "tutorial", 3 ),
            new pair( "program", -4 )];
             
// Size of the array
let N = arr.length;
 
// Function call to print
    // String corresponding to
    // maximum absolute subarray sum
    maximumAbsSum(arr, N);
 
// This code is contributed by unknown2108
</script>


 
 

Output: 

geeks for geeks tutorial

 

Time Complexity: O(N)
Auxiliary Space: O(1) 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads