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

边界测试用例未通过:连续子数组和问题代码优化咨询

问题分析与解决方案

你遇到的这个问题核心在于没有严格满足连续子数组长度至少为2的要求,同时原有的滑动窗口逻辑本身就不适合处理这类“子数组和为k倍数”的问题(尤其是k=0或者存在0元素的场景)。

你的代码问题点

在测试用例{0,1,0},k=0时,你的代码初始化curSum = nums[0] = 0,进入i=1的循环后,直接触发了if(curSum==0 && k1==0)的条件返回true,但此时对应的子数组只有第一个元素[0],长度为1,完全不符合题目中“长度至少为2”的要求。

除此之外,你的滑动窗口逻辑还有其他缺陷:

  • 当k很大时,会漏掉那些和大于k但其实是k倍数的长段子数组(比如示例2的情况,你的代码可能无法检测到总和为42的子数组);
  • 没有考虑到前缀和余数重复的情况(这是解决这类问题的核心思路)。

正确的解决思路:前缀和+哈希表

要判断是否存在长度≥2的连续子数组和为k的倍数,我们可以利用前缀和的余数性质:

  • 当k≠0时,如果两个不同位置的前缀和对k取余的结果相同,那么这两个位置之间的子数组和就是k的倍数;
  • 当k=0时,我们需要找是否存在两个不同位置的前缀和都是0(因为此时子数组和为0,即0的倍数),且这两个位置的索引差≥2。

具体实现步骤:

  1. 维护一个哈希表,存储前缀和的余数(或0值)对应的最早出现的索引;
  2. 初始化哈希表,把{0: -1}放进去(处理前缀和本身就是k倍数的情况,比如前两个元素和为k);
  3. 遍历数组,计算当前前缀和,根据k是否为0分别处理:
    • k≠0时,计算当前前缀和对k取余的结果(题目中是 non-negative 整数,前缀和非负,余数无需处理负数);
    • k=0时,直接用前缀和的值作为键;
  4. 如果当前键已经在哈希表中,且当前索引与哈希表中存储的索引差≥2,说明存在符合条件的子数组,返回true;
  5. 如果当前键不在哈希表中,就把它和当前索引存入哈希表;
  6. 遍历结束后返回false。

修改后的代码

class Solution {
    public boolean checkSubarraySum(int[] nums, int k) {
        // 哈希表存储前缀和余数(或0值)对应的最早索引
        HashMap<Integer, Integer> remainderMap = new HashMap<>();
        remainderMap.put(0, -1);
        int prefixSum = 0;
        
        for (int i = 0; i < nums.length; i++) {
            prefixSum += nums[i];
            
            int key;
            if (k != 0) {
                // 处理k≠0的情况,计算余数
                key = prefixSum % k;
            } else {
                // k=0时,直接用前缀和作为键
                key = prefixSum;
            }
            
            if (remainderMap.containsKey(key)) {
                // 检查索引差是否≥2
                if (i - remainderMap.get(key) >= 2) {
                    return true;
                }
            } else {
                // 只存储最早出现的索引,保证后续索引差最大
                remainderMap.put(key, i);
            }
        }
        
        return false;
    }
}

测试用例验证

对于nums={0,1,0}, k=0:

  • 前缀和依次为0,1,1;
  • 初始哈希表有{0:-1};
  • i=0时,prefixSum=0,key=0,哈希表中存在,i - (-1)=1 < 2,不返回;
  • i=1时,prefixSum=1,key=1,哈希表中没有,存入{1:1};
  • i=2时,prefixSum=1,key=1,哈希表中存在,i -1=1 <2,不返回;
  • 遍历结束返回false,符合预期。

对于你给出的两个示例:

  • 示例1[23,2,4,6,7], k=6:前缀和余数依次为5,1,5,5,0;当i=2时,余数5已在i=0出现过,2-0=2≥2,返回true;
  • 示例2[23,2,6,4,7], k=6:前缀和余数依次为5,1,1,5,0;当i=4时,余数0对应索引-1,4 - (-1)=5≥2,返回true。

这样就能完美处理所有边界情况,包括k=0、数组中有0元素的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:32:01