当前位置: 首页 > 知识库问答 >
问题:

乘积不能被k整除的子数组数

鞠晋
2023-03-14

给定一个数组,我想计算子数组的数量(连续的),当取的乘积不会被k整除。

例如。设 A = [1, 2, 3, 4, 5, 6] 和 K = 2

则使乘积不能被 K 整除的子数组数为 2:

{1}
{3}
{5}

其余的都可以被2整除。

{1, 2}
{1, 2, 3}
{1, 2, 3, 4}
{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5, 6}
{2}
{2, 3}
{2, 3, 4}
{2, 3, 4, 5} etc..

我首先尝试计算子数组(n)(n 1)/2的总数,然后使用mod减去可被k整除的子数组的数量,但它不起作用。我该如何解决这个问题?

这(错误地)计算了乘积可被K整除的子阵列数:

int curr = 1;
    int x = 0;
    for (int i = 0; i < a.length; i++) {
        curr = curr * a[i] % k;
        if (curr == 0) {
            curr = 1;
            if (x > 0)
                ans = ans.subtract(NumberUtils.nChooseR(x + 1, 2));
            if (a[i] % k != 0) {
                x = 1;
            } else {
                x = 0;
            }
        } else {
            x++;
        }
    }
    if (x != 0) {
        ans = ans.subtract(NumberUtils.nChooseR(x + 1, 2));
    }
    return ans;

一个稍微相关的问题是这个问题,但它涉及加法,因此不能在这里应用。

编辑:对数组大小的约束是10^5,对数组元素的限制是10^9。因此,我正在寻找线性或线性时间的解决方案

共有1个答案

勾通
2023-03-14

“大局”:

>

  • 很容易看出,如果 [l, r] 子数组积可被 K 整除,则 [l, r 1] 和 [l - 1, r] 的乘积也是如此。

    因此,如果我们可以有效地计算子数组模K的乘积的值,我们可以只移动两个指针(左指针正好向右移动一个,右指针不断增加,直到乘积等于零模K)。这样,我们将获得从左指针位置开始且其积可被K整除的子数组的数量。答案将只是左指针所有值的总和。

    问题:我们无法显式存储产品(它太大)。我们也不能做模运算,因为移动左指针需要模除法。我们可能没有反比。

    解决方案1:

    让我们用一棵段树来计算任意子阵列在< code>O(log N)时间内的模K的乘积(我们只需构建树,并在每个节点中存储对应范围模K的乘积。现在我们只需要将查询范围分解成的所有节点的这些值相乘(模K)。我们可以使用两个指针,因为我们可以有效地计算任何子数组模K的乘积。

    解决方案2:

    分而治之。

    让我们将数组分成两个(几乎)相等的部分,并递归地解决每个部分的问题。现在我们只需要计算从前半部分开始并以第二部分结束的好子数组的数量。但是每个这样的子数组的乘积是[l, m][m 1, r]部分的乘积(所有计算都是模K完成的)。但是m是固定的(它是拆分数组的位置)。因此,我们可以在线性时间内为所有l预计算[l, m]的乘积,为所有r预计算[m 1, r]的乘积。现在我们可以再次使用两个指针(它们分别用0和m 1初始化)。我们可以在线性时间内“合并”两半,因此总时间复杂度再次为O(N log N)

  •  类似资料:
    • 求其和可被K整除的最长子数组。在O(n)中可能吗?如果不是,它能比n^2更好地完成吗?

    • 我在一次面试中有以下问题,尽管我给出了一个可工作的实现,但它不够高效。 数组A的切片是任何一对整数(P,Q),使得0≤ P≤ Q 我被要求编写的函数必须返回可被K整除的切片数。预期的时间复杂度为O(max(N, K)),空间复杂度为O(K)。 我的解决方案是最简单的,一个循环套一个循环,检查每一个切片:O(n^2) 我一直在想,但我真的不知道如何在O(max(N, K))中做到这一点。 它可能是子

    • 给定一个n个正整数的序列,我们需要计算其和可被k整除的连续子序列。 约束条件:N最多为10^6,每个元素最多为10 ^9,K最多为100 示例:设N=5,K=3,数组为1 2 3 4 1 这里的答案是4 说明:存在4个子序列,其和可被3整除,它们是: 我的尝试是: 但显然它的方法很差。对于这个问题,他们有更好的方法吗?请帮帮忙。 完整问题:https://www.hackerrank.com/co

    • 给定一个大小为n, n的数组

    • 问题内容: 给出了长度为 n 的数组。查找子数组元素的乘积之和。 说明 数组 A* = 长度 3的 [2,3,4] 。 * 长度为 2的 子数组= [2,3],[3,4],[2,4] [2,3] 中元素的乘积= 6 [3,4] 中元素的乘积= 12 [2,4] 中元素的乘积= 8 长度 2 = 6 + 12 + 8 = 26的子数组的总和 同样,对于长度 3 ,Sum = 24 因此,乘积以模 1

    • 我一直在练习算法问题,我遇到了这个问题。 给定一个数组(+VE和-VE),我必须找到一个连续的子数组,这样,和可以被任意数K整除,并且该子数组可能是最大和。对于 和,可被k整除的最大和子数组是 ,目前我所能想到的是,每个元素都有两种可能,要么包含在目标子数组中,要么不包含在目标子数组中。但这将是一个指数算法。 编辑:是否有可能在线性时间内解决这个问题。请帮忙