Problem
Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals to k.
Examples
Example 1:
| |
Example 2:
| |
Solution
Let’s take an example not given in the question by taking negative numbers
| |
So, the answer should be ‘1’ as their is only one subarray whose sum is 0 i.e (-1 + 1)
Method 1 - Brute Force
- Since we are very obedient person and don’t want to do anything extra from our side.
- So, we will try to generate the sum of each subarray and if matches with
k, then increment our answer. - Like, this is the most basic thing we can do.
| |
Complexity
- ⏰ Time complexity:
O(n^2) - 🧺 Space complexity:
O(1)
Method 2 - Using Prefix Sum but Still Naive
- Calculate the prefix sum of the array.
- Now loop over the array in a nested way,
prefix[j] - prefix[i]is equal tok. Increment our count: For eg. consider the array[1, 2, 3, 4, 5]andk=9, we have below prefix sum.
| |
We see index 0 and index 3 has difference of k. Likewise index 2 and index 4 have difference k. That is our answer:
Code
| |
Complexity
- ⏰ Time complexity:
O(n^2) - 🧺 Space complexity:
O(n)
So, now we use map.
Method 3 - Using Prefix Sum with Map
- Instead of traversing the whole array every time, can we able to store prefix sum already and then check with that.
- So, with the help of an
unordered map, we will store sum.
Intuition Before Code
So, suppose we have an array as arr[]: [1,2,3,4,5] and k = 9
Our answer will be ‘2’ i.e (2 + 3 + 4 and 4 + 5)
Now, if we store our prefix sum array then it should looks like:
| |
How, we will find our subarray (2 + 3 + 4) using prefix sum, see:
- Look at prefix sum array. Index 0 and 3. Prefix sum at index
0is1and index3is10. - Now question - How much prefix sum increased from index
0to3? Ans - Difference between 2 sums at index0and3, i.e. (10-1) = 9. - If (
10 - 1) sum increases from index0to3, then we can say that, ok, this difference, should be the sum of elements greater than index 0, and upto index 3, i.e from index 1 to index 3,right. - Now, if we will see then we find out (
10 - 1) is nothing but our ‘k’ that is 9. - Why use map? So, we find out, that a subarray may also exist if this particular condition satisified, i.e
(prefix[i] - k) should exist in our map,
How? see,
If
prefix[i] - prefix[j] = kwherei > j(i, j any index, in our case they are i = 3, j = 0)prefix[i] - k = prefix[j], (simple maths) i.e if we are able to find (prefix[i] - k) is exist in our map, i.e prefix[j] so, we can say that from index j + 1 to i, the sum of the elements is k, right na, hence it proves that their exist an subarray from index j + 1 to i whose sum is k.
Now, for subarray (4 + 5) we again find this valid see -
| |
if we see our prefix sum at
index 4then it is15and also prefix sum atindex 2is6. So, we can say that from index 2 to 4 our prefix sum increases from 6 to 15, right,So on putting a question, HOW MUCH ? means how much our sum increase from index 2 to index 4. Answer is
15-6=9, which is equal tok.So, we find out, that a subarray may also exist if this particular condition satisified, i.e (
prefix[i] - k) should exist in our map, right na,How? see,
If
prefix[i] - prefix[j] = kwhere i > j (i, j any index, in our case they are i = 4, j = 2)prefix[i] - k = prefix[j]na, (simple maths)i.e if we are able to find (
prefix[i] - k) is exist in our map, i.eprefix[j]so, we can say that from index j + 1 to i, the sum of the elements is k, right na, hence it proves that their exist an subarray from index j + 1 to i whose sum is k.I hope u got the reason now, why we will do (
prefix[i] - k) in our code.
In the code below, we are not using prefix array, but sum variable, which stores current prefix value. And then we are saving it in the hashmap, instead of array.
Code
| |
Complexity
- ⏰ Time complexity:
O(n) - 🧺 Space complexity:
O(n)