均值舍入为零的子数组的数量

Posted

技术标签:

【中文标题】均值舍入为零的子数组的数量【英文标题】:Number of subarrays whose mean rounds to zero 【发布时间】:2020-12-31 16:47:27 【问题描述】:

你有一个整数数组。您必须找到子数组的数量,这意味着(这些元素的总和除以这些元素的数量)四舍五入到零。 我已经用 O(n^2) 时间解决了这个问题,但效率不够。有办法吗?

example:

[-1, 1, 5, 4]
subarrays which mean rounds to zero are: 
   [-1, 1] = 0 , [-1, 1, 5, -4] = 1/4 which rounds to zero

【问题讨论】:

【参考方案1】:

表示由对(前缀总和,cnt)组成的新数组,其中第一个元素是前缀总和,第二个元素是元素个数,例如,

int[] arr = [-1, 1, 5 ,4]:
int[] narr = [(0, 0), (-1, 1), (0, 2), (5, 3), (9, 4)]

问题被转换为narr 中的(i, j) 计数对,其中i < jMath.abs(narr[j][0] - narr[i][0]) < narr[j][1] - narr[i][1] = j - i 进一步归结为:

narr[j][0] - j < narr[i][0] - i < narr[i][0] + i < narr[j][0] + j

所以问题进一步转换为以下问题:

对于一些区间:[[1, 2], [-1, 0], ...](最初为空),给定一个区间 [x, y],计算有多少区间完全在[x, y],然后我们添加这个区间,并重复这个过程总共 N 次。 (如何管理区间的数据结构成为关键问题)

如果我们只是暴力迭代每个间隔并进行验证,查询时间复杂度为 O(N),插入时间复杂度为 O(1),总共 O(N^2)

如果我们使用平方分解,查询时间复杂度是O(sqrt(N)),插入时间复杂度是O(1),总共是O(Nsqrt(N))

如果我们使用treap(使用first或者second作为优先级,使用另一个作为key),我们可以达到的平均总时间复杂度是O(NlgN)

如果你不了解平方分解或treap的技术,我建议你先阅读几篇文章。

更新:

经过 30 分钟的仔细思考,我发现 treap 无法达到 O(NlgN) 平均时间复杂度。 相反,我们可以使用 2d segment tree 来实现 O(NlgNlgN): 请改为阅读这篇文章: 2d segment tree

【讨论】:

非常感谢您的回复。您是否可以使用 treap 方法帮助我编写代码?我不太清楚如何实现

以上是关于均值舍入为零的子数组的数量的主要内容,如果未能解决你的问题,请参考以下文章

常用函数

和为零的子矩阵

Subarray Sum

为啥起始位置为零的子字符串不会在 SQL 中引发错误?

算法练习——和最接近于零的子数组

是否有 ARM NEON 指令用于该轮向零的有符号右移?