Number of subarrays having absolute sum greater than K | Set-2
Given an integer array arr[] of length N consisting of both positive and negative integers, the task is to find the number of sub-arrays with the absolute value of sum greater than a given positive number K.
Examples:
Input : arr[] = {-1, 0, 1}, K = 0
Output : 4
All possible sub-arrays and there total sum:
{-1} = -1
{0} = 0
{1} = 1
{-1, 0} = -1
{0, 1} = 1
{-1, 0, 1} = 0
Thus, 4 sub-arrays have absolute
value of sum greater than 0.
Input : arr[] = {2, 3, 4}, K = 4
Output : 3
Approach: A similar approach that works on a positive integer array is discussed here.
In this article, we will look at an algorithm that solves this problem for both positive and negative integers.
- Create a prefix-sum array of the given array.
- Sort the prefix-sum array.
- Create variable ans, find the number of elements in the prefix-sum array with value lesser than -K or greater than K, and initialize ans with this value.
- Now, iterate the sorted prefix-sum array and for every index i, find the index of the first element with a value greater than arr[i] + K. Let’s say this index is j.
Then ans can be updated as ans += N – j as the number of elements in the prefix-sum array larger than the value of arr[i]+K will be equal to N – j.
To find the index j, perform binary search on prefix-sum array. Specifically, find the upper-bound on the value of prefix-sum[i] + k.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
#define maxLen 30
using namespace std;
int findCnt( int arr[], int n, int k)
{
int ans = 0;
for ( int i = 1; i < n; i++) {
arr[i] += arr[i - 1];
if (arr[i] > k or arr[i] < -1 * k)
ans++;
}
if (arr[0] > k || arr[0] < -1 * k)
ans++;
sort(arr, arr + n);
for ( int i = 0; i < n; i++)
ans += n -
(upper_bound(arr, arr + n, arr[i] + k) - arr);
return ans;
}
int main()
{
int arr[] = { -1, 4, -5, 6 };
int n = sizeof (arr) / sizeof ( int );
int k = 0;
cout << findCnt(arr, n, k);
}
|
Java
import java.util.*;
class GFG
{
static int maxLen = 30 ;
static int findCnt( int arr[], int n, int k)
{
int ans = 0 ;
for ( int i = 1 ; i < n; i++)
{
arr[i] += arr[i - 1 ];
if (arr[i] > k || arr[i] < - 1 * k)
ans++;
}
if (arr[ 0 ] > k || arr[ 0 ] < - 1 * k)
ans++;
Arrays.sort(arr);
for ( int i = 0 ; i < n; i++)
ans += n - upper_bound(arr, 0 , n, arr[i] + k);
return ans;
}
static int upper_bound( int [] a, int low,
int high, int element)
{
while (low < high)
{
int middle = low + (high - low)/ 2 ;
if (a[middle] > element)
high = middle;
else
low = middle + 1 ;
}
return low;
}
public static void main(String[] args)
{
int arr[] = { - 1 , 4 , - 5 , 6 };
int n = arr.length;
int k = 0 ;
System.out.println(findCnt(arr, n, k));
}
}
|
C#
using System;
class GFG
{
static int findCnt( int []arr, int n, int k)
{
int ans = 0;
for ( int i = 1; i < n; i++)
{
arr[i] += arr[i - 1];
if (arr[i] > k || arr[i] < -1 * k)
ans++;
}
if (arr[0] > k || arr[0] < -1 * k)
ans++;
Array.Sort(arr);
for ( int i = 0; i < n; i++)
ans += n - upper_bound(arr, 0, n, arr[i] + k);
return ans;
}
static int upper_bound( int [] a, int low,
int high, int element)
{
while (low < high)
{
int middle = low + (high - low)/2;
if (a[middle] > element)
high = middle;
else
low = middle + 1;
}
return low;
}
public static void Main()
{
int []arr = { -1, 4, -5, 6 };
int n = arr.Length;
int k = 0;
Console.WriteLine(findCnt(arr, n, k));
}
}
|
Python3
from bisect import bisect as upper_bound
maxLen = 30
def findCnt(arr, n, k):
ans = 0
for i in range ( 1 ,n):
arr[i] + = arr[i - 1 ]
if (arr[i] > k or arr[i] < - 1 * k):
ans + = 1
if (arr[ 0 ] > k or arr[ 0 ] < - 1 * k):
ans + = 1
arr = sorted (arr)
for i in range (n):
ans + = n - upper_bound(arr,arr[i] + k)
return ans
arr = [ - 1 , 4 , - 5 , 6 ]
n = len (arr)
k = 0
print (findCnt(arr, n, k))
|
Javascript
<script>
var maxLen = 30;
function upper_bound(a, low, high, element)
{
while (low < high)
{
var middle = low + parseInt((high - low)/2);
if (a[middle] > element)
high = middle;
else
low = middle + 1;
}
return low;
}
function findCnt(arr, n, k)
{
var ans = 0;
for ( var i = 1; i < n; i++) {
arr[i] += arr[i - 1];
if (arr[i] > k || arr[i] < -1 * k)
ans++;
}
if (arr[0] > k || arr[0] < -1 * k)
ans++;
arr.sort((a,b)=>a-b)
for ( var i = 0; i < n; i++)
ans += (n - upper_bound(arr, 0, n, arr[i] + k));
return ans;
}
var arr = [ -1, 4, -5, 6 ];
var n = arr.length;
var k = 0;
document.write( findCnt(arr, n, k));
</script>
|
Time complexity : O(Nlog(N))
Auxiliary Space: O(1), no extra space is required, so it is a constant
Last Updated :
07 Dec, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...