给定长度为N的正整数和负整数组成的整数数组arr [] ,任务是找到绝对和值大于给定正数K的子数组的数目。
例子:
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 4.
Input : arr[] = {2, 3, 4}, K = 4
Output : 3
方法:本文讨论了一种适用于正整数数组的类似方法。
在本文中,我们将研究一种可以解决正整数和负整数的问题的算法。
- 创建给定数组的前缀和数组。
- 对前缀和数组进行排序。
- 创建变量ans ,在前缀和数组中找到小于-K或大于K的元素数,并使用该值初始化ans 。
- 现在,迭代排序的前缀和数组,并为每个索引i查找值大于arr [i] + K的第一个元素的索引。假设这个索引是j 。
然后,可以将ans更新为ans + = N – j,因为前缀和数组中的元素数大于arr [i] + K的值将等于N – j 。
要找到索引j ,请对前缀和数组进行二分查找。具体来说,找到prefix-sum [i] + k的值的上限。
下面是上述方法的实现
C++
// C++ implementation of the above approach
#include
#define maxLen 30
using namespace std;
// Function to find required value
int findCnt(int arr[], int n, int k)
{
// Variable to store final answer
int ans = 0;
// Loop to find prefix-sum
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++;
// Sorting prefix-sum array
sort(arr, arr + n);
// Loop to find upper_bound
// for each element
for (int i = 0; i < n; i++)
ans += n -
(upper_bound(arr, arr + n, arr[i] + k) - arr);
// Returning final answer
return ans;
}
// Driver code
int main()
{
int arr[] = { -1, 4, -5, 6 };
int n = sizeof(arr) / sizeof(int);
int k = 0;
// Function to find required value
cout << findCnt(arr, n, k);
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
static int maxLen = 30;
// Function to find required value
static int findCnt(int arr[], int n, int k)
{
// Variable to store final answer
int ans = 0;
// Loop to find prefix-sum
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++;
// Sorting prefix-sum array
Arrays.sort(arr);
// Loop to find upper_bound
// for each element
for (int i = 0; i < n; i++)
ans += n - upper_bound(arr, 0, n, arr[i] + k);
// Returning final answer
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;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { -1, 4, -5, 6 };
int n = arr.length;
int k = 0;
// Function to find required value
System.out.println(findCnt(arr, n, k));
}
}
// This code is contributed by 29AjayKumar
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to find required value
static int findCnt(int []arr, int n, int k)
{
// Variable to store final answer
int ans = 0;
// Loop to find prefix-sum
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++;
// Sorting prefix-sum array
Array.Sort(arr);
// Loop to find upper_bound
// for each element
for (int i = 0; i < n; i++)
ans += n - upper_bound(arr, 0, n, arr[i] + k);
// Returning final answer
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;
}
// Driver code
public static void Main()
{
int []arr = { -1, 4, -5, 6 };
int n = arr.Length;
int k = 0;
// Function to find required value
Console.WriteLine(findCnt(arr, n, k));
}
}
// This code is contributed by AnkitRai01
Python3
# Python3 implementation of the above approach
from bisect import bisect as upper_bound
maxLen=30
# Function to find required value
def findCnt(arr, n, k):
# Variable to store final answer
ans = 0
# Loop to find prefix-sum
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
# Sorting prefix-sum array
arr=sorted(arr)
# Loop to find upper_bound
# for each element
for i in range(n):
ans += n - upper_bound(arr,arr[i] + k)
# Returning final answer
return ans
# Driver code
arr = [-1, 4, -5, 6]
n = len(arr)
k = 0
# Function to find required value
print(findCnt(arr, n, k))
# This code is contributed by mohit kumar 29
输出:
10
时间复杂度: O(Nlog(N))