First subarray with negative sum from the given Array

Given an array arr[] consisting of N integers, the task is to find the start and end indices of the first subarray with a Negative Sum. Print “-1” if no such subarray exists.

Note: In the case of multiple negative-sum subarrays in the given array, the first subarray refers to the subarray with the lowest starting index.

Examples:

Input: arr[] = {3, 3, -4, -2}
Output: 1 2
Explanation:
The first subarray with negative sum is from index 1 to 2 that is arr[1] + arr[2] = -1.

Input: arr[] = {1, 2, 3, 10}.
Output: -1
Explanation:
No Subarray with negative sum exists.



Naive Approach: The naive approach is to generate all subarrays from left to right in the array and check whether any of these subarrays have a negative-sum or not. If yes then print the starting and ending index of that subarray.

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

Efficient Approach: The idea is to solve the problem using Prefix Sum and Hashing. Below are the steps:

  1. Calculate the Prefix Sum of the array and store it into HashMap.
  2. Iterate through the array and for every ith index, where i ranges from [0, N – 1], check if the element at ith index is negative or not. If so, then arr[i] is the required subarray.
  3. Otherwise, find an index starting from i + 1, where the prefix sum is smaller than the prefix sum upto i.
  4. If any such index is found in the above step, then the subarray from indices {i, index} gives the first negative subarray.
  5. If no such subarray is found, print “-1”. Otherwise, print the obtained subarray.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to check if a sum less
// than pre_sum is present
int b_search(int pre_sum,
             map<int, vector<int> >& m,
             int index)
{
    // Returns an iterator either equal
    // to given key or next greater
    auto it = m.lower_bound(pre_sum);
  
    if (it == m.begin())
        return -1;
  
    // Decrement the iterator
    it--;
  
    // Check if the sum found at
    // a greater index
    auto it1
        = lower_bound(it->second.begin(),
                      it->second.end(),
                      index);
  
    if (*it1 > index)
        return *it1;
  
    return -1;
}
  
// Function to return the index
// of first negative subarray sum
vector<int> findSubarray(int arr[], int n)
{
    // Stores the prefix sum- index
    // mappings
    map<int, vector<int> > m;
  
    int sum = 0;
  
    // Stores the prefix sum of
    // the original array
    int prefix_sum[n];
  
    for (int i = 0; i < n; i++) {
        sum += arr[i];
  
        // Check if we get sum negative
        // starting from first element
        if (sum < 0)
            return { 0, i };
  
        prefix_sum[i] = sum;
        m[sum].push_back(i);
    }
  
    // Iterate through array find
    // the sum which is just less
    // then the previous prefix sum
    for (int i = 1; i < n; i++) {
  
        // Check if the starting element
        // is itself negative
        if (arr[i] < 0)
  
            // arr[i] becomes the required
            // subarray
            return { i, i };
  
        else {
            int pre_sum = prefix_sum[i - 1];
  
            // Find the index which forms
            // negative sum subarray
            // from i-th index
            int index = b_search(pre_sum,
                                 m, i);
  
            // If a subarray is found
            // starting from i-th index
            if (index != -1)
                return { i, index };
        }
    }
  
    // Return -1 if no such
    // subarray is present
    return { -1 };
}
  
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 1, 2, -1, 3, -4, 3, -5 };
  
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // Function Call
    vector<int> res = findSubarray(arr, n);
  
    // If subarray does not exist
    if (res[0] == -1)
        cout << "-1" << endl;
  
    // If the subarray exists
    else {
        cout << res[0]
             << " " << res[1];
    }
    return 0;
}

chevron_right


Output:

0 6

Time Complexity: O(N * log N)
Auxiliary Space: O(N)

competitive-programming-img




My Personal Notes arrow_drop_up

Competitive Programming enthusiast 4 star at codechef 5 star at Hackerrank love to solve problems

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.