Skip to content
Related Articles
Open in App
Not now

Related Articles

First subarray with negative sum from the given Array

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 21 Oct, 2022
Improve Article
Save Article

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 in HashMap.
  2. Iterate through the array and for every ith index, where i ranges from [0, N – 1], check if the element at the 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 up to 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++




// 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;
}

Java




/*package whatever //do not write package name here */
// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG {
 
    // lower bound for a map's key
    public static int
    lowerBound(Map<Integer, List<Integer> > m, int pre_sum)
    {
        int ans = -1;
        for (Integer key : m.keySet()) {
            if (key >= pre_sum) {
                ans = key;
                break;
            }
        }
        return ans;
    }
 
    // lower bound for a list
    public static int lowerBoundList(List<Integer> li,
                                     int target)
    {
        int ans = -1;
        for (int i = 0; i < li.size(); i++) {
            if (li.get(i) >= target) {
                ans = i;
                break;
            }
        }
        return ans;
    }
 
    // Function to check if a sum less
    // than pre_sum is present
    public static int
    b_search(int pre_sum, Map<Integer, List<Integer> > m,
             int index)
    {
       
        // Returns an iterator either equal
        // to given key or next greater
        int it = lowerBound(m, pre_sum);
 
        if (it == 0)
            return -1;
 
        // Decrement the iterator
        it--;
 
        List<Integer> map_list = new ArrayList<Integer>();
        map_list = m.get(it);
       
        // Check if the sum found at
        // a greater index
        int it1 = lowerBoundList(map_list, index);
 
        if (map_list.get(it1) > index)
            return map_list.get(it1);
 
        return -1;
    }
 
    // Function to return the index
    // of first negative subarray sum
    public static List<Integer> findSubarray(int[] arr,
                                             int n)
    {
       
        // Stores the prefix sum- index
        // mappings
        Map<Integer, List<Integer> > m
            = new HashMap<Integer, List<Integer> >();
 
        for (int i = 0; i < n; i++) {
            List<Integer> a = new ArrayList<Integer>();
            a.add(0);
            m.put(i, a);
        }
 
        int sum = 0;
 
        // Stores the prefix sum of
        // the original array
        int[] prefix_sum = new int[n];
 
        for (int i = 0; i < n; i++) {
            sum += arr[i];
 
            // Check if we get sum negative
            // starting from first element
            if (sum < 0) {
 
                List<Integer> xyz
                    = new ArrayList<Integer>();
                xyz.add(0);
                xyz.add(i);
                return xyz;
                // return { 0, i };
            }
            List<Integer> xyz = new ArrayList<Integer>();
            xyz.add(i);
            prefix_sum[i] = sum;
            m.put(sum, xyz);
        }
 
        // 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
                List<Integer> ret
                    = new ArrayList<Integer>();
                ret.add(i);
                ret.add(i);
                return ret;
                // 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) {
 
                    List<Integer> ret
                        = new ArrayList<Integer>();
                    ret.add(i);
                    ret.add(index);
                    return ret;
                    // return { i, index };
                }
            }
        }
 
        // Return -1 if no such
        // subarray is present
        List<Integer> re = new ArrayList<Integer>();
        re.add(-1);
        return re;
    }
 
    public static void main(String[] args)
    {
       
        // Given array arr[]
        int[] arr = { 1, 2, -1, 3, -4, 3, -5 };
 
        int n = arr.length;
 
        // Function Call
        List<Integer> res = new ArrayList<Integer>();
        res = findSubarray(arr, n);
 
        // If subarray does not exist
        if (res.get(0) == -1)
            System.out.println("-1");
 
        // If the subarray exists
        else {
            System.out.print(res.get(0));
            System.out.print(" ");
            System.out.println(res.get(1));
        }
    }
}
 
// This code is contributed by akashish__

Python3




# lower bound for a dictionary's key    
def lowerBound(m, pre_sum):
  ans = -1
  for key in m:
    if (key >= pre_sum):
      ans = key
      break
  return ans
 
# lower bound for a list
def lowerBoundList(li, target):
  ans = -1
  for i in range(0,len(li)):
    if (li[i] >= target):
      ans = i
      break
  return ans
 
# Function to check if a sum less
# than pre_sum is present
def b_search(pre_sum, m, index):
   
  # Returns an iterator either equal
  # to given key or next greater
  it = lowerBound(m, pre_sum)
  if (it == 0):
    return -1
 
  # Decrement the iterator
  it = it - 1
 
  map_list = m[it]
  # Check if the sum found at
  # a greater index
  it1 = lowerBoundList(map_list, index)
 
  if (map_list[it1] > index):
    return map_list[it1]
 
  return -1
 
# Function to return the index
# of first negative subarray sum
def findSubarray(arr, n):
   
  # Stores the prefix sum- index
  # mappings
  m = {}
   
  for i in range(0,n):
    a = [0]
    m[i] = a
 
  sum = 0
 
  # Stores the prefix sum of
  # the original array
  prefix_sum = [0]*n
   
  for i in range(0,n):
    sum += arr[i]
 
    # Check if we get sum negative
    # starting from first element
    if (sum < 0):
      xyz = [0,i]
      return xyz
 
    xyz = [i]
    prefix_sum[i] = sum
    m[sum] = xyz
 
  # Iterate through array find
  # the sum which is just less
  # then the previous prefix sum
  for i in range(1,n):
       
    # Check if the starting element
    # is itself negative
    if (arr[i] < 0):
         
      # arr[i] becomes the required
      # subarray
      ret = [i,i]
      return ret
    else:
         
      pre_sum = prefix_sum[i - 1]
 
      # Find the index which forms
      # negative sum subarray
      # from i-th index
      index = b_search(pre_sum, m, i)
 
      # If a subarray is found
      # starting from i-th index
      if (index != -1):
        ret = [i,index]
        return ret
 
  # Return -1 if no such
  # subarray is present
  re = [-1]
  return re
   
# Given array arr[]
arr = [ 1, 2, -1, 3, -4, 3, -5 ]
 
n = len(arr)
 
# Function Call
res = findSubarray(arr, n)
 
# If subarray does not exist
if (res[0] == -1):
  print("-1")
# If the subarray exists
else:
  print(res)
 
# This code is contributed by akashish__

C#




using System;
using System.Collections.Generic;
 
public class GFG
{
     
  // lower bound for a dictionary's key    
    public static int
    lowerBound(Dictionary<int, List<int> > m, int pre_sum)
    {
        int ans = -1;
        foreach(KeyValuePair<int, List<int> > kvp in m)
        {
            if (kvp.Key >= pre_sum) {
                ans = kvp.Key;
                break;
            }
        }
        return ans;
    }
 
      // lower bound for a list
    public static int lowerBoundList(List<int> li,
                                     int target)
    {
        int ans = -1;
        for (int i = 0; i < li.Count; i++) {
            if (li[i] >= target) {
                ans = i;
                break;
            }
        }
        return ans;
    }
 
    // Function to check if a sum less
    // than pre_sum is present
    public static int
    b_search(int pre_sum, Dictionary<int, List<int> > m,
             int index)
    {
        // Returns an iterator either equal
        // to given key or next greater
        int it = lowerBound(m, pre_sum);
 
        if (it == 0)
            return -1;
 
        // Decrement the iterator
        it--;
 
        List<int> map_list = new List<int>();
        map_list = m[it];
        // Check if the sum found at
        // a greater index
        int it1 = lowerBoundList(map_list, index);
 
        if (map_list[it1] > index)
            return map_list[it1];
 
        return -1;
    }
 
    // Function to return the index
    // of first negative subarray sum
    public static List<int> findSubarray(int[] arr, int n)
    {
        // Stores the prefix sum- index
        // mappings
        Dictionary<int, List<int> > m
            = new Dictionary<int, List<int> >();
       
      for(int i=0;i<n;i++)
      {
        List<int> a = new List<int>();
        a.Add(0);
          m.Add(i,a);
      }
 
        int sum = 0;
 
        // Stores the prefix sum of
        // the original array
        int[] prefix_sum = new int[n];
 
        for (int i = 0; i < n; i++) {
            sum += arr[i];
 
            // Check if we get sum negative
            // starting from first element
            if (sum < 0) {
 
                List<int> xyz = new List<int>();
                xyz.Add(0);
                xyz.Add(i);
                return xyz;
                // return { 0, i };
            }
 
            prefix_sum[i] = sum;
            m[sum].Add(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
                List<int> ret = new List<int>();
                ret.Add(i);
                ret.Add(i);
                return ret;
              // 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) {
 
                    List<int> ret = new List<int>();
                    ret.Add(i);
                    ret.Add(index);
                    return ret;
                    // return { i, index };
                }
            }
        }
 
        // Return -1 if no such
        // subarray is present
        List<int> re = new List<int>();
        re.Add(-1);
        return re;
    }
 
    static public void Main()
    {
        // Given array arr[]
        int[] arr = { 1, 2, -1, 3, -4, 3, -5 };
 
        int n = arr.Length;
 
        // Function Call
        List<int> res = new List<int>();
        res = findSubarray(arr, n);
 
        // If subarray does not exist
        if (res[0] == -1)
            Console.WriteLine("-1");
 
        // If the subarray exists
        else {
            Console.WriteLine(res[0] + " " + res[1]);
        }
    }
}
 
// This code is contributed by akashish__

Javascript




<script>
 
// lower bound for a dictionary's key    
function lowerBound(m, pre_sum)
{
    let ans = -1;
    for (const [key, value] of Object.entries(m)) {
        if (key >= pre_sum) {
            ans = key;
            break;
        }
         
    }
    return ans;
}
 
  // lower bound for a list
function lowerBoundList(li, target)
{
    let ans = -1;
    for (let i = 0; i < li.Count; i++) {
        if (li[i] >= target) {
            ans = i;
            break;
        }
    }
    return ans;
}
 
// Function to check if a sum less
// than pre_sum is present
function b_search(pre_sum, m, index)
{
    // Returns an iterator either equal
    // to given key or next greater
    let it = lowerBound(m, pre_sum);
 
    if (it == 0)
        return -1;
 
    // Decrement the iterator
    it--;
 
    map_list = [];
    map_list = m[it];
    // Check if the sum found at
    // a greater index
    let it1 = lowerBoundList(map_list, index);
 
    if (map_list[it1] > index)
        return map_list[it1];
 
    return -1;
}
 
// Function to return the index
// of first negative subarray sum
function findSubarray(/*int[]*/ arr, n)
{
    // Stores the prefix sum- index
    // mappings
    m = {};
   
  for(let i=0;i<n;i++)
  {
    a = [0];
    m[i]=a;
  }
 
    let sum = 0;
 
    // Stores the prefix sum of
    // the original array
    let prefix_sum = new Array(n);
 
    for (let i = 0; i < n; i++) {
        sum += arr[i];
 
        // Check if we get sum negative
        // starting from first element
        if (sum < 0) {
            xyz = [0,i];
            return xyz;
        }
 
        prefix_sum[i] = sum;
        m[sum] = i;
    }
 
    // Iterate through array find
    // the sum which is just less
    // then the previous prefix sum
    for (let i = 1; i < n; i++) {
 
        // Check if the starting element
        // is itself negative
        if (arr[i] < 0) {
            // arr[i] becomes the required
            // subarray
            ret = [i,i];
            return ret;
        }
        else {
            let pre_sum = prefix_sum[i - 1];
 
            // Find the index which forms
            // negative sum subarray
            // from i-th index
            let index = b_search(pre_sum, m, i);
 
            // If a subarray is found
            // starting from i-th index
            if (index != -1) {
                ret = [i,index];
                return ret;
            }
        }
    }
 
    // Return -1 if no such
    // subarray is present
    re = [-1];
    return re;
}
// Given array arr[]
let arr = [ 1, 2, -1, 3, -4, 3, -5 ];
 
let n = arr.length;
 
// Function Call
let res = findSubarray(arr, n);
 
// If subarray does not exist
if (res[0] == -1)
    console.log("-1");
 
// If the subarray exists
else {
    console.log(res);
}
 
// This code is contributed by akashish__
 
</script>

Output:

0 6

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

Related Topic: Subarrays, Subsequences, and Subsets in Array


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!