📜  总和等于其长度的子数组的计数

📅  最后修改于: 2021-09-17 07:02:58             🧑  作者: Mango

给定一个大小为N的数组arr[] ,任务是找到其元素之和等于其中元素数的子数组的数量。

例子:

朴素的方法:想法是生成数组的所有子数组,如果子数组的元素之和等于其中的元素数,则计算该子数组。检查所有子数组后打印计数。

时间复杂度: O(N 2 )
辅助空间: O(N)

高效方法:这个问题可以通过观察转化为一个更简单的问题。如果数组的所有元素都递减 1 ,则数组 arr[] 的所有子数组的总和等于其元素数与在新数组中找到总和为 0 的子数组的数量相同(由所有元素递减形成) arr[ ] 的元素乘以 1)。以下是步骤:

  1. 将所有数组元素减 1。
  2. 使用prefix[0] = arr[0]初始化前缀数组。
  3. 从左到右遍历给定数组arr[] ,从索引 1 开始,并将前缀和数组更新为pref[i] = pref[i-1] + arr[i]
  4. 答案初始化为 0。
  5. 从左到右迭代前缀数组pref[]并将答案增加映射中当前元素的值。
  6. 增加地图中当前元素的值。
  7. 在上述步骤之后打印answer的值。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function that counts the subarrays
// with sum of its elements as its length
int countOfSubarray(int arr[], int N)
{
    // Decrementing all the elements
    // of the array by 1
    for (int i = 0; i < N; i++)
        arr[i]--;
 
    // Making prefix sum array
    int pref[N];
    pref[0] = arr[0];
 
    for (int i = 1; i < N; i++)
        pref[i] = pref[i - 1] + arr[i];
 
    // Declare map to store count of
    // elements upto current element
    map mp;
    int answer = 0;
 
    // To count all the subarrays
    // whose prefix sum is 0
    mp[0]++;
 
    // Iterate the array
    for (int i = 0; i < N; i++) {
 
        // Increment answer by count of
        // current element of prefix array
        answer += mp[pref[i]];
        mp[pref[i]]++;
    }
 
    // Return the answer
    return answer;
}
 
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 1, 1, 0 };
    int N = sizeof arr / sizeof arr[0];
 
    // Function call
    cout << countOfSubarray(arr, N);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
class GFG{
 
// Function that counts the subarrays
// with sum of its elements as its length
static int countOfSubarray(int arr[], int N)
{
    // Decrementing all the elements
    // of the array by 1
    for (int i = 0; i < N; i++)
        arr[i]--;
 
    // Making prefix sum array
    int []pref = new int[N];
    pref[0] = arr[0];
 
    for (int i = 1; i < N; i++)
        pref[i] = pref[i - 1] + arr[i];
 
    // Declare map to store count of
    // elements upto current element
    HashMap mp = new HashMap();
    int answer = 0;
 
    // To count all the subarrays
    // whose prefix sum is 0
    mp.put(0, 1);
 
    // Iterate the array
    for (int i = 0; i < N; i++)
    {
 
        // Increment answer by count of
        // current element of prefix array
 
        if(mp.containsKey(pref[i]))
        {
            answer += mp.get(pref[i]);
            mp.put(pref[i], mp.get(pref[i]) + 1);
             
        }
        else
        {
            mp.put(pref[i], 1);
        }
    }
 
    // Return the answer
    return answer;
}
 
// Driver Code
public static void main(String[] args)
{
    // Given array arr[]
    int arr[] = { 1, 1, 0 };
    int N = arr.length;
 
    // Function call
    System.out.print(countOfSubarray(arr, N));
}
}
 
// This code is contributed by sapnasingh4991


Python3
# Python3 program for the above approach
from collections import defaultdict
 
# Function that counts the subarrays
# with sum of its elements as its length
def countOfSubarray(arr, N):
 
    # Decrementing all the elements
    # of the array by 1
    for i in range(N):
        arr[i] -= 1
 
    # Making prefix sum array
    pref = [0] * N
    pref[0] = arr[0]
 
    for i in range(1, N):
        pref[i] = pref[i - 1] + arr[i]
 
    # Declare map to store count of
    # elements upto current element
    mp = defaultdict(lambda : 0)
    answer = 0
 
    # To count all the subarrays
    # whose prefix sum is 0
    mp[0] += 1
 
    # Iterate the array
    for i in range(N):
 
        # Increment answer by count of
        # current element of prefix array
        answer += mp[pref[i]]
        mp[pref[i]] += 1
 
    # Return the answer
    return answer
 
# Driver Code
 
# Given array arr[]
arr = [ 1, 1, 0 ]
N = len(arr)
 
# Function call
print(countOfSubarray(arr, N))
 
# This code is contributed by Shivam Singh


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function that counts the subarrays
// with sum of its elements as its length
static int countOfSubarray(int []arr, int N)
{
    // Decrementing all the elements
    // of the array by 1
    for (int i = 0; i < N; i++)
        arr[i]--;
 
    // Making prefix sum array
    int []pref = new int[N];
    pref[0] = arr[0];
 
    for (int i = 1; i < N; i++)
        pref[i] = pref[i - 1] + arr[i];
 
    // Declare map to store count of
    // elements upto current element
    Dictionary mp = new Dictionary();
    int answer = 0;
 
    // To count all the subarrays
    // whose prefix sum is 0
    mp.Add(0, 1);
 
    // Iterate the array
    for (int i = 0; i < N; i++)
    {
 
        // Increment answer by count of
        // current element of prefix array
 
        if(mp.ContainsKey(pref[i]))
        {
            answer += mp[pref[i]];
            mp[pref[i]]= mp[pref[i]] + 1;   
        }
        else
        {
            mp.Add(pref[i], 1);
        }
    }
 
    // Return the answer
    return answer;
}
 
// Driver Code
public static void Main(String[] args)
{
    // Given array []arr
    int []arr = { 1, 1, 0 };
    int N = arr.Length;
 
    // Function call
    Console.Write(countOfSubarray(arr, N));
}
}
 
// This code is contributed by sapnasingh4991


Javascript


输出:
3

时间复杂度: O(N * Log(N))
辅助空间: O(N)