连续子数组和

Continuous Subarray sum

我在 Leetcode 上遇到了这个问题,我看到了解决方案,但我无法理解它为什么有效。它适用于什么 属性 的模数? 怎么能只看前面出现的取模结果就说找到了和等于k的子数组呢?

问题:

给定一个非负数列表和一个目标整数k,写一个函数检查数组是否有大小至少为2且总和为k的倍数的连续子数组,即求和到 n*k,其中 n 也是一个整数。

示例 1: 输入:[23, 2, 4, 6, 7], k=6 输出:真 解释:因为 [2, 4] 是一个大小为 2 且总和为 6 的连续子数组。

Question Link

解法:

public boolean checkSubarraySum(int[] nums, int k) {
    Map<Integer, Integer> map = new HashMap<Integer, Integer>(){{put(0,-1);}};;
    int runningSum = 0;
    for (int i=0;i<nums.length;i++) {
        runningSum += nums[i];
        if (k != 0) runningSum %= k; 
        Integer prev = map.get(runningSum);
        if (prev != null) {
        if (i - prev > 1) return true;
        }
        else map.put(runningSum, i);
    } 
    return false;
 }

Solution Link

这实际上是一个众所周知的问题,只是对其进行了简单的改动,如果你想要的话,这里有一篇关于 GFG 上更简单版本的文章:Find subarray with given sum

总体思路是保留遇到的所有数字的总和并将它们插入地图中。当你继续你检查你是否已经遇到一个值 actual_total_sum - target_sum (也就是说你在地图中设置的值是否相等到 actual_total_sum - target_sum),如果你有,你会发现自己是一个给出所需值的子数组。

现在如果你明白应该没有任何问题,但让我澄清一切以确保:

您添加到地图中的数字基本上表示从 0 到 "index at which they were added" 的所有元素的总和,因此您有整数表示索引的总计值[0,0], [0,1], [0,2],... 所以,如果您已经添加了值 ,请检查您的地图actual_total_sum - target_sum 你问的是,"Is there a pair of indices [0,x] being equal to actual_total_sum - target_sum" 如果是,那就意味着子数组 [x+1, actual_index] 等于 target_sum.

现在你应该明白了简单版的解法,现在是时候解释leetcode版本的解法了。

的转折很简单,而不是插入子数组 total_sum[0,0], [0,1], [ 0,2],... 你插入 total_sum%k。因此,如果您已经添加了 (actual_total_sum%k) - target_sum 值,请检查您的地图,"Is there a pair of indices [0,x] being equal to (actual_total_sum%k) - target_sum" 如果是,则说明子数组[x+1,actual_index]等于target_sum的倍数。 对于问题的最后一部分,您必须确保子数组的长度 > 2 这很容易,您只需检查 actual_index-(x+1) >= 1 与解决方案中所写的 actual_index-x > 1 相同。

抱歉,耽搁了,解释花了一些时间写,但我希望他们足够清楚,如果没有,请不要犹豫,要求澄清!