Given an array of positive integers nums and a positive integer target, return the minimal length of a subarray whose sum is greater than or equal to target. If there is no such subarray, return 0 instead.
Example 1:
Input:
target = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation:
The subarray [4,3] has the minimal length under the problem constraint.
I was able to successfully complete the question with the sliding window technique but I am looking for some help to optimize the time run /execute & generate the output. Current time complexity is O(n).
class Solution(object):
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
current_sum=nums[0]
possible_combinations=[]
result=float("inf")
start=0
end=0
target_sum=target
if sum(nums)<target:
return 0
elif target in nums:
return 1
else:
while start < len(nums) and end < len(nums):
if current_sum >= target_sum:
result=min(len(nums[start:end + 1]), result)
current_sum -= nums[start]
start += 1
elif current_sum < target_sum:
end += 1
if end < len(nums):
current_sum += nums[end]
if result ==float("inf"):
return 0
return result
There are 2 significant performance problems:
You can remove the part:
This runs through your array twice on every run, even if it will probably only apply to a small percentage of test cases. Your
while-loop covers those cases, taking a little more time though (so maybe test the effect, as if e.g. 95% of the test cases havesum(nums)<target, removing this edge case will slow your code down).In
you create a copy of the subarray just to get its length, while you know the length already: it is
end-start+1. So you can replace it withAdditionally, you may want to try to end the loop early if the result is
1, as it cannot get lower than this - but it depends on the test data if that has a performance effect, or if this additional condition even increases the average run time:You can get rid of some of your comparisons, but those will probably only have a marginal performance impact (and probably don't make the code prettier or more readable). Some examples that come to mind:
you do not need to test for
elif current_sum < target_sum, since it is the only option left afterif current_sum >= target_sumis false, so you can just useelseyou could add the test if you reached the end of your array into the else-block (as only there,
endis increased), then you can remove it from the while loop (so you save one comparison whenstartis increased), e.g. something like:similarly for the
start < len(nums) and result != 1-test that is only relevant if you are in the if-blockAs a side note, your function currently would fail on an empty list (because
current_sum=nums[0]would fail). It might be specified as not empty somewhere (although not by your docstring), apparently does not cause problems (until it does) and fixing it will most likely not improve performance, but it would fail any code audit, so you might want to keep it in mind.