给定大小为N的数组arr [] ,任务是计算给定数组arr []的子数组的总数,该子数组具有非零和。
例子:
Input: arr[] = {-2, 2, -3}
Output: 4
Explanation:
The subarrays with non zero sum are: [-2], [2], [2, -3], [-3]. All possible subarray of the given input array are [-2], [2], [-3], [2, -2], [2, -3], [-2, 2, -3]. Out of these [2, -2] is not included in the count because 2+(-2) = 0 and [-2, 2, -3] is not selected because one the subarray [2, -2] of this array has a zero sum of elements.
Input: arr[] = {1, 3, -2, 4, -1}
Output: 15
Explanation:
There are 15 subarray for the given array {1, 3, -2, 4, -1} which has a non zero sum.
方法:
解决上述问题的主要思想是使用“前缀和数组”和“地图数据结构”。
- 首先,构建给定数组的Prefix sum数组,并使用以下公式检查子数组是否有0个元素和。
Sum of Subarray[L, R] = Prefix[R] – Prefix[L – 1]. So, If Sum of Subarray[L, R] = 0
Then, Prefix[R] – Prefix[L – 1] = 0. Hence, Prefix[R] = Prefix[L – 1]
- 现在,从1迭代到N,并保留一个Hash表以存储该元素先前出现的索引和一个变量(例如last) ,并将其初始化为0。
- 检查Prefix [i]是否已存在于哈希中。如果是,则将last更新为last = max(last,hash [Prefix [i]] +1) 。否则,在答案前添加i-最后更新哈希表。
下面是上述方法的实现:
C++
// C++ program to Count the total number of
// subarrays for a given array such that its
// subarray should have non zero sum
#include
using namespace std;
// Function to build the Prefix sum array
vector PrefixSumArray(int arr[], int n)
{
vector prefix(n);
// Store prefix of the first position
prefix[0] = arr[0];
for (int i = 1; i < n; i++)
prefix[i] = prefix[i - 1] + arr[i];
return prefix;
}
// Function to return the Count of
// the total number of subarrays
int CountSubarray(int arr[], int n)
{
vector Prefix(n);
// Calculating the prefix array
Prefix = PrefixSumArray(arr, n);
int last = 0, ans = 0;
map Hash;
Hash[0] = -1;
for (int i = 0; i <= n; i++) {
// Check if the element already exists
if (Hash.count(Prefix[i]))
last = max(last, Hash[Prefix[i]] + 1);
ans += max(0, i - last);
// Mark the element
Hash[Prefix[i]] = i;
}
// Return the final answer
return ans;
}
// Driver code
int main()
{
int arr[] = { 1, 3, -2, 4, -1 };
int N = sizeof(arr) / sizeof(arr[0]);
cout << CountSubarray(arr, N);
}
Java
// Java program to count the total number of
// subarrays for a given array such that its
// subarray should have non zero sum
import java.util.*;
class GFG{
// Function to build the Prefix sum array
static int[] PrefixSumArray(int arr[], int n)
{
int []prefix = new int[n];
// Store prefix of the first position
prefix[0] = arr[0];
for(int i = 1; i < n; i++)
prefix[i] = prefix[i - 1] + arr[i];
return prefix;
}
// Function to return the Count of
// the total number of subarrays
static int CountSubarray(int arr[], int n)
{
int []Prefix = new int[n];
// Calculating the prefix array
Prefix = PrefixSumArray(arr, n);
int last = 0, ans = 0;
HashMap Hash = new HashMap();
Hash.put(0, -1);
for(int i = 0; i <= n; i++)
{
// Check if the element already exists
if (i < n && Hash.containsKey(Prefix[i]))
last = Math.max(last,
Hash.get(Prefix[i]) + 1);
ans += Math.max(0, i - last);
// Mark the element
if (i < n)
Hash.put(Prefix[i], i);
}
// Return the final answer
return ans;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 3, -2, 4, -1 };
int N = arr.length;
System.out.print(CountSubarray(arr, N));
}
}
// This code is contributed by amal kumar choubey
Python3
# Python3 program to count the total number
# of subarrays for a given array such that
# its subarray should have non zero sum
# Function to build the prefix sum array
def PrefixSumArray(arr, n):
prefix = [0] * (n + 1);
# Store prefix of the first position
prefix[0] = arr[0];
for i in range(1, n):
prefix[i] = prefix[i - 1] + arr[i];
return prefix;
# Function to return the count of
# the total number of subarrays
def CountSubarray(arr, n):
Prefix = [0] * (n + 1);
# Calculating the prefix array
Prefix = PrefixSumArray(arr, n);
last = 0; ans = 0;
Hash = {};
Hash[0] = -1;
for i in range(n + 1):
# Check if the element already exists
if (Prefix[i] in Hash):
last = max(last, Hash[Prefix[i]] + 1);
ans += max(0, i - last);
# Mark the element
Hash[Prefix[i]] = i;
# Return the final answer
return ans;
# Driver code
if __name__ == "__main__" :
arr = [ 1, 3, -2, 4, -1 ];
N = len(arr);
print(CountSubarray(arr, N));
# This code is contributed by AnkitRai01
C#
// C# program to count the total number of
// subarrays for a given array such that its
// subarray should have non zero sum
using System;
using System.Collections.Generic;
class GFG{
// Function to build the Prefix sum array
static int[] PrefixSumArray(int []arr, int n)
{
int []prefix = new int[n];
// Store prefix of the first position
prefix[0] = arr[0];
for(int i = 1; i < n; i++)
prefix[i] = prefix[i - 1] + arr[i];
return prefix;
}
// Function to return the Count of
// the total number of subarrays
static int CountSubarray(int []arr, int n)
{
int []Prefix = new int[n];
// Calculating the prefix array
Prefix = PrefixSumArray(arr, n);
int last = 0, ans = 0;
Dictionary Hash = new Dictionary();
Hash.Add(0, -1);
for(int i = 0; i <= n; i++)
{
// Check if the element already exists
if (i < n && Hash.ContainsKey(Prefix[i]))
last = Math.Max(last,
Hash[Prefix[i]] + 1);
ans += Math.Max(0, i - last);
// Mark the element
if (i < n)
Hash.Add(Prefix[i], i);
}
// Return the readonly answer
return ans;
}
// Driver code
public static void Main(String[] args)
{
int []arr = {1, 3, -2, 4, -1};
int N = arr.Length;
Console.Write(CountSubarray(arr, N));
}
}
// This code is contributed by shikhasingrajput
15
时间复杂度: O(N)