-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Continuous Subarray sum #113
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
## Continous Subarray Sum | ||
|
||
<p> | ||
<img align="center" width="800px" alt="Question Screenshot" src="./../../Images/ContinuousSubarraySum/question.png"> | ||
</p> | ||
|
||
--- | ||
|
||
### Motivation | ||
We are given an array of Integers `nums` and `K`. we have to find a continuous subset of the array of `length>=2` whose sum is of the form `N*K` where `N` is any integer. | ||
|
||
|
||
### Solution-1 : Naive Way | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe change the heading to |
||
|
||
The naive solution involves traversing all the subset of `nums` whose `length>=2` and checking for `nums[i:j]%K==0` where `i<j` and `nums[i:j]= nums[i]+nums[i+1]+...+nums[j-1]+nums[j]`. While traversing the subsets we explicitily need handle the case `K=0` because `nums[i:j]%K` will throw `DivideByZeroException`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While traversing the subsets we |
||
|
||
|
||
#### Algorithm | ||
1. Create all the subsets of `nums` array whole `length>=2`. | ||
2. Traverse the subsets and check if their sum is a multiple of `K` | ||
3. While traversing the subsets check whether `K=0` which requires sum of the elements in the subset be equal to zero. | ||
|
||
<p> | ||
<img align="center" width="800px" alt="Naive Algorithm" src="./../../Images/ContinuousSubarraySum/ContinuousSubArraySum-NaiveAlgo.png"> | ||
</p> | ||
|
||
This solution will throw `Time Limit Exceeded` error when run on leet code. | ||
|
||
|
||
|
||
### Solution-2 : Dynamic Programming | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not exactly a dynamic programming solution. We are just doing some preprocessing to avoid repeated computation. Any DP solution has two main properties:
This solution doesn't fit the bill as far as these conditions are concerned. It would be better to name it as |
||
In the previous solution we were repeatedly calculating the sum of the subsets. Here, we try to preprocess the array so that we don't have to calculate the sum everytime. Let us see how we accomplish this. | ||
|
||
Let's say | ||
|
||
``` | ||
sum[0:0] = nums[0] | ||
sum[0:1] = nums[0] + nums[1] | ||
sum[0:2] = nums[0] + nums[1] + nums[2] | ||
sum[0:3] = nums[0] + nums[1] + nums[2] + nums[3] | ||
``` | ||
from above, we can conclude that | ||
|
||
``` | ||
sum[2:3] = nums[2]+nums[3] = sum[0:3] - sum[0:1] | ||
``` | ||
|
||
If the above procedure is implemented, it will save us from repetitive recomputation of sum of subsets for which we already calculated. | ||
|
||
We create a temporary array called `dp` same length as of input where `dp[i]=sum[0:i]` | ||
|
||
``` | ||
dp[i] = nums[0] + nums[1] +...+ nums[i] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename the array |
||
|
||
``` | ||
|
||
<p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You'd have to change the image to change the DP array to something like a preprocessed array or something. |
||
<img align="center" width="800px" alt="dp" src="./../../Images/ContinuousSubarraySum/dp-creation.png"> | ||
</p> | ||
|
||
#### Algorithm | ||
1. Create a array called `dp` where `dp[i] = nums[0:i]` | ||
2. We will check each subset for the condition `dp[j]-dp[i]=N*K` where `i<j` and `j-i>1`. | ||
3. The above step is similar to the one we used in Solution-1 except this time we wont need to recompute the sum for each subset generated. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mention the complexity analysis right after this section as is mentioned in the template. |
||
|
||
### Solution-3 : Hashmap | ||
Let us assume any two index positions(i,j) and `0<i<j<len(nums)` in `dp` array where | ||
|
||
``` | ||
dp[i] = p*K ie dp[i]%K=0 | ||
dp[j] = q*K ie dp[j]%K=0 | ||
|
||
``` | ||
Let us take a difference of the above two | ||
|
||
``` | ||
dp[j] - dp[i] = (q-p)*K | ||
``` | ||
which transforms to | ||
|
||
``` | ||
dp[j] - dp[i] = N*K where N is any integer | ||
``` | ||
|
||
From the above we can conclude that, while traversing the array if we store `dp[i]%K` in a hashmap and check if `dp[j]%K` already exists in hashmap and check if `j-i>1` then we have a continous subarray sum. | ||
|
||
The handling of the case `K=0` is same as the previous methods. This is a serious improvement in time complexity from the solution-2. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be great to have an Algorithm section like in the previous two approaches to explain this algorithm in more detail. Also, if possible, add a figure here to showcase the algorithm. That would be awesome to have! |
||
|
||
|
||
#### Complexity Analysis | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's better to mention the complexity analysis for each solution there and then rather than in the end for all three solutions. Also, a one-line explanation can be added in my opinion for each of the complexity sections just to add a bit of clarity even if they are obvious enough |
||
|
||
Solution-1 | ||
|
||
* Time Complexity: `O(N^3)` where `N` is the length of the input. | ||
* Space Complexity: `O(1)` | ||
|
||
Solution-2 | ||
|
||
* Time Complexity: `O(N^2)` where `N` is the length of the input. | ||
* Space Complexity: `O(N)` where `N` is the length of the input. This space is occupied by `dp` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change the name |
||
|
||
Solution-3 | ||
|
||
* Time Complexity: `O(N)` where `N` is the length of the input. | ||
* Space Complexity: `O(N+k)` where `N` is the length of the input and `k` is size of the hashmap . The space is occupied by `dp` and `hashmap` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change the name |
||
|
||
#### Link to OJ | ||
https://leetcode.com/problems/continuous-subarray-sum/ | ||
|
||
--- | ||
Article contributed by [Arihant Sai](https://github.com/Arihant1467) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
class Solution { | ||
public: | ||
bool checkSubarraySum(vector<int>& nums, int k) { | ||
|
||
int n=nums.size(); | ||
for(int i=0;i<n-1;++i){ | ||
for(int j=i+1;j<n;++j){ | ||
int summation = 0; | ||
for(auto it=nums.begin()+i;it!=nums.begin()+j+1;++it){ | ||
summation+=*it; | ||
} | ||
|
||
if(k==0){ | ||
if(summation==0){ | ||
return true; | ||
} | ||
}else if(summation%k==0){ | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
class Solution: | ||
def checkSubarraySum(self, nums: List[int], k: int) -> bool: | ||
|
||
for i in range(len(nums)-1): | ||
for j in range(i+1,len(nums)): | ||
summation = sum(nums[i:j+1]) | ||
if k==0: | ||
if summation==0: | ||
return True | ||
elif summation%k==0: | ||
return True | ||
return False |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
class Solution(object): | ||
def checkSubarraySum(self, nums, k): | ||
""" | ||
:type nums: List[int] | ||
:type k: int | ||
:rtype: bool | ||
""" | ||
if len(nums)<2: | ||
return False | ||
|
||
dp = [0]*len(nums) | ||
dp[0]=nums[0] | ||
|
||
for i in range(1,len(nums)): | ||
dp[i]=dp[i-1]+nums[i] | ||
|
||
if k==0 and dp[i]==0: | ||
return True | ||
elif k and dp[i]%k==0: | ||
return True | ||
|
||
for i in range(0,len(nums)-2): | ||
for j in range(i+2,len(nums)): | ||
if dp[j]-dp[i]==0 and k==0: | ||
return True | ||
elif k and (dp[j]-dp[i])%k==0: | ||
return True | ||
|
||
return False |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
class Solution(object): | ||
def checkSubarraySum(self, nums, k): | ||
""" | ||
:type nums: List[int] | ||
:type k: int | ||
:rtype: bool | ||
""" | ||
|
||
dp = [0]*len(nums) | ||
result = {} | ||
dp[0] = nums[0] | ||
for i in range(1,len(nums)): | ||
dp[i] = dp[i-1]+nums[i] | ||
|
||
if len(nums)<2: | ||
return False | ||
|
||
if k==0: | ||
for i in range(1,len(nums)): | ||
if nums[i]==0 and nums[i-1]==0: | ||
return True | ||
return False | ||
|
||
for i in range(len(dp)): | ||
if not i==0 and dp[i]%k==0: | ||
return True | ||
else: | ||
if not (dp[i]%k in result.keys()): | ||
result[dp[i]%k]=i | ||
else: | ||
if i-result[dp[i]%k]>1: | ||
return True | ||
|
||
return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wWe have to find a continuo