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-
// 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;
} |
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 ));
}
}
} |
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 ])
|
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]);
}
}
} |
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:
- Calculate the Prefix Sum of the array and store it in HashMap.
- 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.
- Otherwise, find an index starting from i + 1, where the prefix sum is smaller than the prefix sum up to i.
- If any such index is found in the above step, then the subarray from indices {i, index} gives the first negative subarray.
- If no such subarray is found, print “-1”. Otherwise, print the obtained subarray.
Below is the implementation of the above approach:
// 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;
} |
/*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__ |
# 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__ |
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__ |
<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> |
0 6
Time Complexity: O(N * log N) Auxiliary Space: O(N)
Related Topic: Subarrays, Subsequences, and Subsets in Array