Open In App

First subarray with negative sum from the given Array

Last Updated : 04 Dec, 2023
Suggest changes
Share
Like Article
Like
Report

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.

Steps to implement-

  • Declare a vector "ans" to store the answer
  • Run two loops to find all subarrays
  • Simultaneously find the sum of all elements of the subarray
  • If the sum of all elements of the subarray became negative then push starting and last index of the subarray into the vector and return/print that
  • In the last, if nothing got printed or returned then return or print "-1"

Code-

C++
// CPP program for the above approach #include <bits/stdc++.h> using namespace std; // Function to return the index // of first negative subarray sum vector<int> findSubarray(int arr[], int N) {  //To store answer  vector<int> ans;    //Find all subarray  for(int i=0;i<N;i++){  //To store sum of subarray  int sum=0;  for(int j=i;j<N;j++){  //Take this element in finding sum of subarray  sum+=arr[j];    //If subarray has negative sum then store  //its starting and last index in the ans vector  if(sum<0){  ans.push_back(i);  ans.push_back(j);  return ans;  }    }  }    //If any subarray sum is not negative  ans.push_back(-1);  return ans;   } // 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
import java.util.ArrayList; import java.util.List; public class Main {  // Function to return the index of the first negative subarray sum  static List<Integer> findSubarray(int[] arr, int N) {  // To store the answer  List<Integer> ans = new ArrayList<>();  // Find all subarrays  for (int i = 0; i < N; i++) {  // To store the sum of subarray  int sum = 0;  for (int j = i; j < N; j++) {  // Take this element in finding the sum of subarray  sum += arr[j];  // If the subarray has a negative sum, then store  // its starting and last index in the ans list  if (sum < 0) {  ans.add(i);  ans.add(j);  return ans;  }  }  }  // If no subarray sum is negative  ans.add(-1);  return ans;  }  // Driver Code  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 = findSubarray(arr, n);  // If subarray does not exist  if (res.get(0) == -1)  System.out.println("-1");  // If the subarray exists  else {  System.out.println(res.get(0) + " " + res.get(1));  }  } } 
Python3
def find_subarray(arr): # To store answer ans = [] N = len(arr) # Find all subarrays for i in range(N): # To store sum of subarray subarray_sum = 0 for j in range(i, N): # Take this element in finding sum of subarray subarray_sum += arr[j] # If subarray has negative sum, then store its starting and last index in the ans list if subarray_sum < 0: ans.append(i) ans.append(j) return ans # If any subarray sum is not negative ans.append(-1) return ans # Driver Code if __name__ == "__main__": # Given array arr[] arr = [1, 2, -1, 3, -4, 3, -5] # Function Call res = find_subarray(arr) # If subarray does not exist if res[0] == -1: print("-1") # If the subarray exists else: print(res[0], res[1]) 
C#
using System; using System.Collections.Generic; class Program {  // Function to return the index  // of the first negative subarray sum  static List<int> FindSubarray(int[] arr, int N)  {  // To store the answer  List<int> ans = new List<int>();  // Find all subarrays  for (int i = 0; i < N; i++)  {  // To store the sum of the subarray  int sum = 0;  for (int j = i; j < N; j++)  {  // Take this element in finding the sum of the subarray  sum += arr[j];  // If the subarray has a negative sum, then store  // its starting and last index in the ans list  if (sum < 0)  {  ans.Add(i);  ans.Add(j);  return ans;  }  }  }  // If any subarray sum is not negative  ans.Add(-1);  return ans;  }  // Driver Code  static void Main()  {  // Given array arr[]  int[] arr = { 1, 2, -1, 3, -4, 3, -5 };  int n = arr.Length;  // Function Call  List<int> res = FindSubarray(arr, n);  // If the subarray does not exist  if (res[0] == -1)  Console.WriteLine("-1");  // If the subarray exists  else  {  Console.WriteLine(res[0] + " " + res[1]);  }  } } 
JavaScript
function findSubarray(arr) {  let ans = [];    for (let i = 0; i < arr.length; i++) {  let sum = 0;  for (let j = i; j < arr.length; j++) {  sum += arr[j];  // If subarray has negative sum  if (sum < 0) {  ans.push(i);  ans.push(j);  return ans;  }  }  }  // If any subarray sum is not negative  ans.push(-1);  return ans; } // Given array arr let arr = [1, 2, -1, 3, -4, 3, -5]; // Function call let res = findSubarray(arr); // If subarray does not exist if (res[0] === -1)  console.log("-1"); // If the subarray exists else {  console.log(res[0] + " " + res[1]); } 

Output-

0 6

Time Complexity: O(N2), because of two nested loops to find all subarray

Auxiliary Space: O(1), because no extra space has been used

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


Next Article

Similar Reads

Practice Tags :