我在Leetcode上遇到了这个问题,我看到了解决方案,但是我不明白它为什么起作用。它适用于什么性质的模量? 仅仅通过查看模数结果的先前出现,如何说我们发现了一个总和等于k的子数组?
问题:
给出一个非负数和一个目标整数k的列表,编写一个函数来检查数组是否具有大小至少为2的连续子数组,该子数组的总和为k的倍数,即,总和为n * k,其中n也是整数。
示例1: 输入:[23、2、4、6、7],k = 6 输出:真 说明:因为[2,4]是大小为2的连续子数组,总和为6。
解决方案:
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;
}
答案 0 :(得分:2)
这实际上是一个众所周知的问题,但有一个简单的变化,如果您想在此发表有关GFG的更简单版本的文章:Find subarray with given sum
总体思路是,保留所有遇到的数字的总和,并将其插入地图中。继续操作时,请检查是否已经遇到了 actual_total_sum-target_sum 的值(也就是说,您在地图中设置的值是否等于 actual_total_sum-target_sum ),如果有的话,您会发现自己有一个提供所需值的子数组。
现在,如果您了解应该没有任何问题,但是让我澄清一切以确保:
您要添加到地图中的数字基本上表示从0到“添加元素的索引”的所有元素的总和。,因此,您可以使用整数来表示索引 [0,0],[0,1],[0,2], ...因此,通过检查地图是否已经添加了 actual_total_sum-target_sum 值您正在问,“是否有一对索引[0,x]等于 actual_total_sum-target_sum ” ,如果是,则表示子数组[x + 1, Actual_index]等于target_sum。
现在您应该了解较简单版本的解决方案,现在是时候解释leetcode版本的此问题的解决方案了。
唯一的问题是,不是为子数组 [0,0],[0,1],[0,2],... 插入 total_sum 值>您插入 total_sum%k 。因此,通过检查地图是否已经添加了(actual_total_sum%k)-target_sum 值,您会问,“是否存在一对等于[0,x]的索引(actual_total_sum%k)-target_sum “ 如果是,则表示子数组[x + 1,actual_index]等于target_sum的倍数。 对于问题的最后一部分,必须确保子数组的长度> 2,这很容易,您只需检查 actual_index-(x + 1)> = 1 是否相同解决方案中写为 actual_index-x> 1 。
对不起,延迟了一段时间,写了一些解释,但我希望它们足够清楚,如果没有,请不要犹豫,要求澄清!