给定大小为N的数组arr [] ,任务是查找子元素的总和等于子元素数量的子数组的数量。
例子:
Input: N = 3, arr[] = {1, 0, 2}
Output: 3
Explanation:
Total number of subarrays are 6 i.e., {1}, {0}, {2}, {1, 0}, {0, 2}, {1, 0, 2}.
Out of 6 only three subarrays have the number of elements equals to sum of its elements i.e.,
1) {1}, sum = 1, length = 1.
2) {0, 2}, sum = 2, length = 2.
3) {1, 0, 2}, sum = 3, length = 3.
Input: N = 3, arr[] = {1, 1, 0}
Output: 3
Explanation:
Total number of subarrays are 6 i.e. {1}, {1}, {0}, {1, 1}, {1, 0}, {1, 1, 0}.
Out of 6 only three subarrays have the number of elements equals to sum of its elements i.e.,
1) {1}, sum = 1, length = 1.
2) {1}, sum = 1, length = 1.
3) {1, 1}, sum = 2, length = 2.
天真的方法:想法是生成数组的所有子数组,如果子数组的元素总数等于其中的元素数量,则对该子数组进行计数。检查所有子数组后打印计数。
时间复杂度: O(N 2 )
辅助空间: O(N)
高效的方法:通过观察,可以将此问题转换为更简单的问题。如果将数组的所有元素减1 ,则数组arr []的所有子数组的总和等于其元素数,与在新数组中找到总和为0的子数组的数量相同(通过对a进行减法形成) arr []的元素加1)。步骤如下:
- 将所有数组元素减1。
- 使用prefix [0] = arr [0]初始化前缀数组。
- 从索引1开始从左到右遍历给定数组arr [] ,并将前缀和数组更新为pref [i] = pref [i-1] + arr [i] 。
- 将答案初始化为0。
- 从左到右迭代前缀数组pref [] ,并根据映射中当前元素的值递增答案。
- 增加地图中当前元素的值。
- 完成上述步骤后,打印答案的值。
下面是上述方法的实现:
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
3
时间复杂度: O(N * Log(N))
辅助空间: O(N)