Problem Statement
You are given an array of integers nums
and an integer k
. Your task is to find the length of the longest subarray that has a sum equal to k
. If no such subarray exists, return 0
.
Examples
Example 1:
Input: nums = [1, -1, 5, -2, 3], K = 3
Output: 4
Explanation:
The subarray [1, -1, 5, -2] has a sum of 3, which is the longest subarray with sum 3.
Example 2:
Input: nums = [-2, -1, 2, 1], K = 1
Output: 2
Explanation:
The subarray [-1, 2] has a sum of 1, which is the longest subarray with sum 1.
Different Approaches
1️⃣ Brute Force Approach
Algorithm:
- Initialize maxLen to 0.
- Iterate through all subarrays of the given array and calculate their sum.
- If the sum is equal to k, update maxLen with the length of the current subarray.
- Return maxLen.
Dry Run:
Initialization:
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
k = 15
Iterate through the array:
i = 0
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
k = 15
For j = i = 0
sum = 0
maxLength = 0
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
j
sum += nums[j]
= 10
Does it is equal to k
No sum is 10 while k is 15
Increment j
For j = 1
sum = 10
maxLength = 0
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
sum += nums[j]
= 10 + 5
Does it is equal to k
Yes sum is 15 while k is 15
Get its length, j - i + 1
length = 1 - 0 + 1
= 2
Assign max of maxLength and length to maxLength
maxLength = max(maxLength, length)
= max(0, 2)
= 2
For j = 2
sum = 15
maxLength = 2
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
sum += nums[j]
= 15 + 2
= 17
Does it is equal to k
No, sum is 17 while k is 15
So, Increment j
For j = 3
sum = 17
maxLength = 2
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
sum += nums[j]
= 17 + 7
= 24
Does it is equal to k
No, sum is 24 while k is 15
So, Increment j
For j = 4
sum = 24
maxLength = 2
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
sum += nums[j]
= 24 + 1
= 25
Does it is equal to k
No, sum is 25 while k is 15
So, Increment j
For j = 5
sum = 25
maxLength = 2
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
sum += nums[j]
= 25 + 9
= 34
Does it is equal to k
No, sum is 34 while k is 15
So, Increment j
For j = 6
sum = 34
maxLength = 2
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
For j = 6 it went out of bounds so inner loop
will terminate,
Now run for next value of i by fixing next element.
i = 1
:
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
k = 15
For j = i = 1
sum = 0
maxLength = 2
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
j
sum += nums[j]
= 0 + 5
Does it is equal to k
No sum is 5 while k is 15
Increment j
For j = 2
i = 1
k = 15
sum = 5
maxLength = 2
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
sum += nums[j]
= 5 + 2
Does it is equal to k
No sum is 7 while k is 15
Increment j
For j = 3
i = 1
k = 15
sum = 7
maxLength = 2
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
sum += nums[j]
= 7 + 7
= 14
Does it is equal to k
No sum is 14 while k is 15
Increment j
For j = 4
i = 1
k = 15
sum = 14
maxLength = 2
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
sum += nums[j]
= 14 + 1
= 15
Does it is equal to k
Yes, sum is 15 while k is 15
Get its length, j - i + 1
length = 4 - 1 + 1
= 4
Assign max of maxLength and length to maxLength
maxLength = max(maxLength, length)
= max(2, 4)
= 4
For j = 5
i = 1
k = 15
sum = 15
maxLength = 4
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
sum += nums[j]
= 15 + 9
= 24
Does it is equal to k
No, sum is 24 while k is 15
Increment j
For j = 6
i = 1
k = 15
sum = 24
maxLength = 4
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^ ^
| |
i j
The j went out of bounds to array. So, inner
loop will terminate and i is incremented.
Keep doing it until outer loop i < nums.size
And at last return maxLength.
Code Implementation in C++:
#include <bits/stdc++.h>
using namespace std;
class Solution
{
public:
int longestSubarray(vector<int> &nums, int k)
{
int n = nums.size();
int maxLength = 0;
// starting index
for (int startIndex = 0; startIndex < n; startIndex++) {
// ending index
for (int endIndex = startIndex; endIndex < n; endIndex++) {
/* add all the elements of
subarray = nums[startIndex...endIndex] */
int currentSum = 0;
for (int i = startIndex; i <= endIndex; i++) {
currentSum += nums[i];
}
if (currentSum == k)
maxLength = max(maxLength, endIndex - startIndex + 1);
}
}
return maxLength;
}
};
int main()
{
vector<int> a = { -1, 1, 1 };
int k = 1;
// Create an instance of the Solution class
Solution solution;
// Function call to get the result
int len = solution.longestSubarray(a, k);
cout << "The length of the longest subarray is: " << len << "\n";
return 0;
}
Complexity Analysis:
- Time Complexity:
O(n^2)
, wheren
is the number of elements in array. - Space Complexity:
O(1)
2️⃣ Cumulitive Sum using HashMap
Algorithm:
- Initialize a
hashmap
mp to store the prefix sum and its corresponding index.- The key of the hashmap will be the prefix sum.
- The value of the hashmap will be the index of the first occurrence of the prefix sum.
- Initialize
maxLen
to0
andsum
to0
. - Iterate through the array and calculate the prefix sum.
- At each iteration, update the sum by adding the current element.
- If
sum - k
is present inmp
, updatemaxLen
with the maximum length so far.- If
sum - k
is present in the hashmap, it means there exists a subarray with the required sum. - Update
maxLen
with the maximum length of the subarray.
- If
- If sum is not present in
mp
, add it to mp.- If the current prefix sum is not present in the hashmap, add it to the hashmap along with its index.
- Return
maxLen
.
Dry Run:
Initialization:
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
k = 15
maxlen = 0
currentSum = 0
unordered_map(prefixSum, index)
+-----+-----+
| key |value|
+-----+-----+
Iterate over the array:
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
k = 15
maxlen = 0
currentSum = 0
unordered_map(prefixSum, index)
+-----+-----+
| key |value|
+-----+-----+
Iteration 1: i = 0
currentSum += nums[i]
currentSum = 0 + 10
= 10
Check if currentSum is equal to k
No it does not.
Else if
Check if currentSum - target(k) exist in
the map
= 10 - 15
= -5
No it does not exist in the map
Check if currentSum 10, does not exist in map
Yes it does not exist
So add the currentSum as key and index as
value in the map
currentSum = 10, index = 0
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
k = 15
maxlen = 0
currentSum = 10
unordered_map(prefixSum || currentSum, index)
+-----+-----+
| key |value|
+-----+-----+
| 10 | 0 |
+-----+-----+
Iteration 2: i = 1
currentSum += nums[i]
currentSum = 10 + 5
= 15
Check if currentSum is equal to k
Yes it is equal, 15 == 15
set maxlen = i + 1
= 1 + 1
= 2
Check if currentSum 15, does not exist in map
Yes it does not exist
So add the currentSum as key and index as
value in the map
currentSum = 15, index = 1
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
k = 15
maxlen = 2
currentSum = 15
unordered_map(prefixSum || currentSum, index)
+-----+-----+
| key |value|
+-----+-----+
| 10 | 0 |
+-----+-----+
| 15 | 1 |
+-----+-----+
Iteration 3: i = 2
currentSum += nums[i]
currentSum = 15 + 2
= 17
Check if currentSum is equal to k
No, it is not
Else if
Check currentSum - target(k) exist in
the map
= 17 - 15
= 2
No it does not exist in the map
Check if currentSum 17, does not exist in map
Yes it does not exist
So add the currentSum as key and index as
value in the map
currentSum = 17, index = 2
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
k = 15
maxlen = 2
currentSum = 17
unordered_map(prefixSum || currentSum, index)
+-----+-----+
| key |value|
+-----+-----+
| 10 | 0 |
+-----+-----+
| 15 | 1 |
+-----+-----+
| 17 | 2 |
+-----+-----+
Iteration 4: i = 3
currentSum += nums[i]
currentSum = 17 + 7
= 24
Check if currentSum is equal to k
24 != 15
No, it is not
Else if
Check currentSum - target(k) exist in
the map
= 24 - 15
= 9
No it does not exist in the map
Check if currentSum 24, does not exist in map
Yes it does not exist
So add the currentSum as key and index as
value in the map
currentSum = 24, index = 3
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
k = 15
maxlen = 2
currentSum = 24
unordered_map(prefixSum || currentSum, index)
+-----+-----+
| key |value|
+-----+-----+
| 10 | 0 |
+-----+-----+
| 15 | 1 |
+-----+-----+
| 17 | 2 |
+-----+-----+
| 24 | 3 |
+-----+-----+
Iteration 5: i = 4
currentSum += nums[i]
currentSum = 24 + 1
= 25
Check if currentSum is equal to k
25 != 15
No, it is not
Else if
Check currentSum - target(k) exist in
the map
= 25 - 15
= 10
Yes, it does exist in the map
Set maxLen = max(maxLen, i - map[currentSum - k])
maxLen = max(2, 4 - 0)
maxLen = 4
Check if currentSum 25, does not exist in map
Yes it does not exist
So add the currentSum as key and index as
value in the map
currentSum = 25, index = 4
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
k = 15
maxlen = 4
currentSum = 25
unordered_map(prefixSum || currentSum, index)
+-----+-----+
| key |value|
+-----+-----+
| 10 | 0 |
+-----+-----+
| 15 | 1 |
+-----+-----+
| 17 | 2 |
+-----+-----+
| 24 | 3 |
+-----+-----+
| 25 | 4 |
+-----+-----+
Iteration 5: i = 4
currentSum += nums[i]
currentSum = 25 + 9
= 34
Check if currentSum is equal to k
34 != 15
No, it is not
Else if
Check currentSum - target(k) exist in
the map
= 34 - 15
= 9
No, it does not exist in the map
Check if currentSum 34, does not exist in map
Yes it does not exist
So add the currentSum as key and index as
value in the map
currentSum = 34, index = 5
Loop Termination:
+-----+-----+-----+-----+-----+-----+
nums = | 10 | 5 | 2 | 7 | 1 | 9 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
k = 15
maxlen = 4
currentSum = 34
unordered_map(prefixSum || currentSum, index)
+-----+-----+
| key |value|
+-----+-----+
| 10 | 0 |
+-----+-----+
| 15 | 1 |
+-----+-----+
| 17 | 2 |
+-----+-----+
| 24 | 3 |
+-----+-----+
| 25 | 4 |
+-----+-----+
| 34 | 5 |
+-----+-----+
Since i has exceeded the bounds of the array so, loop
will terminate and maxlen contains the answer.
Code Implementation in C++:
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int longestSubarrayWithSumK(vector<int>& nums, int k) {
unordered_map<int, int> mp;
int maxLen = 0;
int sum = 0;
for (int i = 0; i < nums.size(); i++) {
sum += nums[i];
if (sum == k) {
maxLen = i + 1;
}
else if (mp.find(sum - k) != mp.end()) {
maxLen = max(maxLen, i - mp[sum - k]);
}
if (mp.find(sum) == mp.end()) {
mp[sum] = i;
}
}
return maxLen;
}
int main() {
vector<int> nums1 = {1, -1, 5, -2, 3};
int k1 = 3;
cout << "Length of the longest subarray with sum " << k1 << ": " << longestSubarrayWithSumK(nums1, k1) << endl;
vector<int> nums2 = {-2, -1, 2, 1};
int k2 = 1;
cout << "Length of the longest subarray with sum " << k2 << ": " << longestSubarrayWithSumK(nums2, k2) << endl;
return 0;
}
Complexity Analysis:
- Time Complexity:
O(n)
- Space Complexity:
O(n)