给定总和为零的所有连续子数组 [英] Counting all contiguous sub-arrays given sum zero

查看:118
本文介绍了给定总和为零的所有连续子数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定长度为n的随机数(正数和负数)数组,我想要数字连续的子数组,其总和等于零。

Given array of random numbers(positive, and negative) with length n, I want number contiguous sub-arrays which sum equals zero.

示例:
鉴于我有数组 a = {1,-1,2,-2 ,6,-6} ,输出将为 6 ,因为子数组如下:

Example: Given I have array a={1, -1 ,2 , -2, 6, -6}, output will be 6 because sub-arrays are as the following:

1 -1 & 2 -2 & 6 -6 & 1 -1 2 -2 & 2 -2 6 -6 & 1 -1 2 -2 6 -6

我知道蛮力解O(n ^ 2),我想要其他解决方案O(n)或O(n log n)吗?

I know brute force solution O(n^2), I want any another solution O(n), or O(n log n) ?

推荐答案

让数组为a1,。 ..,一个令s0,...,sn为sj = a1 + ... + aj(和s0 = 0)定义的前缀和。从i到j的子数组之和为sj-si-1。对于O(n)/ O(n log n)时间算法,使用映射,计算前缀总和中每个数字的出现次数。总和k在此地图的值中为k选择2。

Let the array be a1, ..., an. Let s0, ..., sn be the prefix sums defined by sj = a1 + ... + aj (and s0 = 0). The sum of the subarray from i to j inclusive is sj - si-1. For an O(n)/O(n log n)-time algorithm, using a map, count the number of occurrences of each number among the prefix sums. Sum k choose 2 for k in the values of this map.

例如,如果我们有您的数组

For example, if we have your array

1 -1 2 -2 6 -6

然后前缀总和是

0 1 0 2 0 6 0

,计数为

0: 4
1: 1
2: 1
3: 1

,输出为4选择2 + 1选择2 + 1选择2 + 1选择2 = 6(其中k选择2 = k(k-1)/ 2)。

and the output is 4 choose 2 + 1 choose 2 + 1 choose 2 + 1 choose 2 = 6 (where k choose 2 = k(k-1)/2).

在Python中:

def countsumzero(lst):
    prefixsums = [0]
    for x in lst:
        prefixsums.append(prefixsums[-1] + x)
    freq = {}
    for y in prefixsums:
        if y in freq:
            freq[y] += 1
        else:
            freq[y] = 1
    return sum(v*(v-1) // 2 for v in freq.values())

这篇关于给定总和为零的所有连续子数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆