【问题标题】:Continuous Subarray sum连续子数组和
【发布时间】:2018-08-13 20:23:24
【问题描述】:

我在 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

【问题讨论】:

  • 你应该开始使用调试器,看看这段代码发生了什么(变量是如何改变的)。除此之外,如果此代码有效,如您所说,在Code Review 中提出此问题更为合适

标签: java modulus


【解决方案1】:

这实际上是一个众所周知的问题,只需稍加改动即可,如果您想要,这里有一篇关于 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 版本的这个问题的解决方案了。

转折只是为了代替插入 total_sum 子数组的值 [0,0], [0,1], [0,2],... 你插入 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

抱歉,耽搁了,解释写得有点久,但我希望他们足够清楚,如果没有,请毫不犹豫地要求澄清!

【讨论】:

  • 谢谢,我研究了原始问题,但无法建立连接。现在,这很有意义。
  • 感谢您的精彩解释
猜你喜欢
  • 2021-01-21
  • 2020-01-22
  • 2013-09-13
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 2020-02-17
相关资源
最近更新 更多