https://leetcode.com/problems/maximum-size-subarray-sum-equals-k/#/description
Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't one, return 0 instead.
Note:
The sum of the entire nums array is guaranteed to fit within the 32-bit signed integer range.
Example 1:
Given nums = [1, -1, 5, -2, 3]
, k = 3
,
return 4
. (because the subarray [1, -1, 5, -2]
sums to 3 and is the longest)
Example 2:
Given nums = [-2, -1, 2, 1]
, k = 1
,
return 2
. (because the subarray [-1, 2]
sums to 1 and is the longest)
Follow Up:
Can you do it in O(n) time?
class Solution(object): def maxSubArrayLen(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int """ # key: sum of numbers so far, nums[:i+1] #value: i sum = {} # key: sum(nums[:i+1]), value: i total = 0 max_len = 0 for i in range(len(nums)): total += nums[i] if total not in sum: sum[total] = i remain = total - k # we only iterate the list once, so we must use seen list to check remainders if remain == 0: max_len = max(i+1, max_len) elif remain in sum: # make sure the max length starts from the left - most element, sum[remain] max_len = max(i - sum[remain], max_len) return max_len
Sol 2:
Using the prefix sum algorithm to achieve the linear time complexity.
"The sum of subarrays add up to k " is equivalent to "The difference of their prefix sums is k".
Thus, we are going to find out the value of element and value - k element in prefix sum array and return the max length.
class Solution(object): def maxSubArrayLen(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int """ # O(n) time and O(n) space # prefix sum algorithm if not nums: return 0 prefix_sum = [0] number_sum = 0 # generate a list of the prefix sums for i in range(len(nums)): number_sum += nums[i] prefix_sum.append(number_sum) # create a hash table that operates on prefix_sum hash = {} max_len = 0 # the greatest length is index of the current element (bigger) minus the index of the left-most element (smaller) for i in range(len(prefix_sum)): if prefix_sum[i] not in hash: hash[prefix_sum[i]] = i # if a previously seen prefix_sum equates to the difference k, find out the left-most one. i.e. the max length if (prefix_sum[i] - k) in hash: max_len = max(max_len, i - hash[prefix_sum[i] - k]) return max_len