📌  相关文章
📜  绝对和大于K |的子数组数套装2

📅  最后修改于: 2021-04-26 18:48:04             🧑  作者: Mango

给定长度为N的正整数和负整数组成的整数数组arr [] ,任务是找到绝对和值大于给定正数K的子数组的数目。

例子:

方法:本文讨论了一种适用于正整数数组的类似方法。

在本文中,我们将研究一种可以解决正整数和负整数的问题的算法。

  1. 创建给定数组的前缀和数组。
  2. 对前缀和数组进行排序。
  3. 创建变量ans ,在前缀和数组中找到小于-K或大于K的元素数,并使用该值初始化ans
  4. 现在,迭代排序的前缀和数组,并为每个索引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))