Continuous Subarray sum

Prasad Madhale :

I came across this problem on Leetcode I saw the solution but I am unable to understand why it works. What property of modulus does it apply? How can we say that we have found a subarray with sum equal to k just by looking at the previous occurence of the modulo result?

Question:

Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer.

Example 1: Input: [23, 2, 4, 6, 7], k=6 Output: True Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6.

Question Link

Solution:

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

tom gautot :

This actually is a well known problem with a simple twist to it, if you want here is an article about the simpler version on GFG : Find subarray with given sum

The overall idea is that you keep the total sum of all the numbers encountered and insert them in a map. As you go on you check if you had already encountered a of value actual_total_sum - target_sum (that is if one on the value you set in your map is equal to actual_total_sum - target_sum), if you have, you found yourself a subarray giving the wanted value.

Now if you understood that there shouldn't be any problem but let me clarify everything to be sure:

The numbers you are adding into your map basically represent the sum of all elements from 0 to "index at which they were added", therefore you have integers indicating the values of totals for indices [0,0], [0,1], [0,2],... SO, by checking in your map if you have already added the value actual_total_sum - target_sum you are asking, "Is there a pair of indices [0,x] being equal to actual_total_sum - target_sum" if yes, that means that the subarray [x+1, actual_index] is equal to the target_sum.

Now you should understand the solution for the simpler version, it's now time to explain the solution for leetcode's version of this problem.

The twist is simply that instead of inserting total_sum value for the subarrays [0,0], [0,1], [0,2],... you insert total_sum%k. SO, by checking in your map if you have already added the value (actual_total_sum%k) - target_sum you are asking, "Is there a pair of indices [0,x] being equal to (actual_total_sum%k) - target_sum" if yes, that means that the subarray [x+1, actual_index] is equal to a multiple of target_sum. And for the last part of the problem, you must make sure the subarray has length > 2 well that's quite easy you just have to check that actual_index-(x+1) >= 1 which is the same as actual_index-x > 1 as written in the solution.

Sorry, for the delay, explanations took a while to write but I hope that they are clear enough, if not, do not hesitate to ask for clarification!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=90971&siteId=1
Recommended