You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

满足长度等于P倍元素和的子数组查找及问题归类咨询

符合条件子数组统计问题解答

1. 高效校验统计方案

核心推导

暴力枚举所有子数组的时间复杂度为O(N²),无法处理N=1e5的规模,我们可以通过数学转换将问题降为线性时间复杂度:
设前缀和数组S,其中S[0] = 0,S[k]为数组前k个元素的和(即A[0]到A[k-1]的和)。对于任意子数组A[i...j](闭区间,长度为j-i+1),其元素和为S[j+1] - S[i],代入题目要求的规则:

子数组长度 = P * 子数组元素和
可得等式:
j - i + 1 = P * (S[j+1] - S[i])
移项后将相同下标的项放在同侧,可得:
P * S[j+1] - (j+1) = P * S[i] - i
此时问题转换为:遍历每个右边界r = j+1,统计此前所有位置中,P*S[i] - i的值等于当前P*S[r] - r的出现次数,该次数即为以r为结尾的符合条件的子数组数量,累加所有次数即可得到总数量。

特殊情况处理

  • 当P=0时,原等式右侧恒为0,而子数组长度最小为1,此时不存在符合条件的子数组,直接返回0即可。
  • 所有计算值需使用long类型存储,避免前缀和叠加、乘以P后超出int范围导致溢出。

复杂度说明

时间复杂度O(N):仅需遍历数组一次,哈希表的存取操作均为O(1)均摊复杂度。
空间复杂度O(N):最坏情况下所有P*S[i] -i的值均不重复,哈希表需要存储N个键值对。

2. 问题分类说明

该问题属于P类问题,不属于NP-hard问题:我们已经找到了确定性的线性时间复杂度解法,可在多项式时间内得到结果,远低于NP-hard问题的求解难度。该问题属于经典的「前缀和+哈希表优化」类子数组计数问题。

C# 实现代码

using System;
using System.Collections.Generic;

public class Solution {
    public static long CountValidSubarrays(int[] A, int P) {
        if (A == null || A.Length == 0 || P == 0) {
            return 0;
        }
        long prefixSum = 0;
        long count = 0;
        Dictionary<long, int> keyCount = new Dictionary<long, int>();
        // 初始化前缀和为0的边界情况
        keyCount.Add(0, 1);
        for (int r = 1; r <= A.Length; r++) {
            prefixSum += A[r - 1];
            long currentKey = (long)P * prefixSum - r;
            if (keyCount.ContainsKey(currentKey)) {
                count += keyCount[currentKey];
                keyCount[currentKey]++;
            } else {
                keyCount.Add(currentKey, 1);
            }
        }
        return count;
    }

    // 测试用例
    public static void Main() {
        int[] A = new int[] {2, -1, 3, 0, 1, 2, 1};
        int P = 2;
        Console.WriteLine(CountValidSubarrays(A, P)); // 输出2,与示例结果匹配
    }
}

内容的提问来源于stack exchange,提问作者user1907849

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 18:36:00