[LeetCode] Minimum Size Subarray Sum
The problem statement has stated that there are both O(n)
and O(nlogn)
solutions to this problem. Let's see the O(n)
solution first (taken from this link), which is pretty clever and short.
1 class Solution { 2 public: 3 int minSubArrayLen(int s, vector<int>& nums) { 4 int start = 0, sum = 0, minlen = INT_MAX; 5 for (int i = 0; i < (int)nums.size(); i++) { 6 sum += nums[i]; 7 while (sum >= s) { 8 minlen = min(minlen, i - start + 1); 9 sum -= nums[start++]; 10 } 11 } 12 return minlen == INT_MAX ? 0 : minlen; 13 } 14 };
Well, you may wonder how can it be O(n)
since it contains an inner while
loop. Well, the key is that the while
loop executes at most once for each starting position start
. Then start
is increased by 1
and the while
loop moves to the next element. Thus the inner while
loop runs at most O(n)
times during the whole for
loop from 0
to nums.size() - 1
. Thus both the for
loop and while
loop has O(n)
time complexity in total and the overall running time is O(n)
.
There is another O(n)
solution in this link, which is easier to understand and prove it is O(n)
. I have rewritten it below.
1 class Solution { 2 public: 3 int minSubArrayLen(int s, vector<int>& nums) { 4 int n = nums.size(); 5 int left = 0, right = 0, sum = 0, minlen = INT_MAX; 6 while (right < n) { 7 do sum += nums[right++]; 8 while (right < n && sum < s); 9 while (left < right && sum - nums[left] >= s) 10 sum -= nums[left++]; 11 if (sum >= s) minlen = min(minlen, right - left); 12 } 13 return minlen == INT_MAX ? 0 : minlen; 14 } 15 };
Now let's move on to the O(nlogn)
solution. Well, this less efficient solution is far more difficult to come up with. The idea is to first maintain an array of accumulated summations of elements innums
. Specifically, for nums = [2, 3, 1, 2, 4, 3]
in the problem statement, sums = [0, 2, 5, 6, 8, 12, 15]
. Then for each element in sums
, if it is not less than s
, we search for the first element that is greater than sums[i] - s
(in fact, this is just what the upper_bound
function does) in sums
using binary search.
Let's do an example. Suppose we reach 12
in sums
, which is greater than s = 7
. We then search for the first element in sums
that is greater than sums[i] - s = 12 - 7 = 5
and we find 6
. Then we know that the elements in nums
that correspond to 6, 8, 12
sum to a number 12 - 5 = 7
which is not less than s = 7
. Let's check for that: 6
in sums
corresponds to 1
in nums
, 8
insums
corresponds to 2
in nums
, 12
in sums
corresponds to 4
in nums
. 1, 2, 4
sum to 7
, which is 12
in sums
minus 5
in sums
.
We add a 0
in the first position of sums
to account for cases like nums = [3], s = 3
.
The code is as follows.
1 class Solution { 2 public: 3 int minSubArrayLen(int s, vector<int>& nums) { 4 vector<int> sums = accumulate(nums); 5 int minlen = INT_MAX; 6 for (int i = 1; i <= nums.size(); i++) { 7 if (sums[i] >= s) { 8 int p = upper_bound(sums, 0, i, sums[i] - s); 9 if (p != -1) minlen = min(minlen, i - p + 1); 10 } 11 } 12 return minlen == INT_MAX ? 0 : minlen; 13 } 14 private: 15 vector<int> accumulate(vector<int>& nums) { 16 vector<int> sums(nums.size() + 1, 0); 17 for (int i = 1; i <= nums.size(); i++) 18 sums[i] = nums[i - 1] + sums[i - 1]; 19 return sums; 20 } 21 int upper_bound(vector<int>& sums, int left, int right, int target) { 22 int l = left, r = right; 23 while (l < r) { 24 int m = l + ((r - l) >> 1); 25 if (sums[m] <= target) l = m + 1; 26 else r = m; 27 } 28 if (sums[r] > target) return r; 29 if (sums[l] > target) return l; 30 return -1; 31 } 32 };
相關文章
- LeetCode 209. Minimum Size Subarray Sum ?LeetCode
- Leetcode 209. Minimum Size Subarray SumLeetCode
- [LeetCode] 523. Continuous Subarray SumLeetCode
- [LeetCode] 560. Subarray Sum Equals KLeetCode
- LeetCode: 560. Subarray Sum Equals KLeetCode
- [LeetCode] 2841. Maximum Sum of Almost Unique SubarrayLeetCode
- B - Minimum Sum
- Range Minimum Sum
- 64. Minimum Path Sum
- 64 - Minimum Path Sum 最小路徑和
- LeetCode | 152. Maximum Product SubarrayLeetCode
- leetcode Sum系列LeetCode
- Leetcode Path SumLeetCode
- [LeetCode] 2831. Find the Longest Equal SubarrayLeetCode
- [LeetCode] 2419. Longest Subarray With Maximum Bitwise ANDLeetCode
- [LeetCode] 727. Minimum Window SubsequenceLeetCode
- Leetcode 39 Combination SumLeetCode
- Leetcode 1 two sumLeetCode
- LeetCode | 1 Two SumLeetCode
- LeetCode 974 Subarray Sums Divisible by K All In OneLeetCode
- LeetCode のminimum-depth-of-binary-treeLeetCode
- leetcode-39-Combination SumLeetCode
- Leetcode 40 Combination Sum IILeetCode
- Leetcode 15 3SumLeetCode
- Leetcode 18 4SumLeetCode
- LeetCode-1 Two SumLeetCode
- LeetCode 112. Path SumLeetCode
- [LeetCode]1.Two SumLeetCode
- python: leetcode - 1 Two SumPythonLeetCode
- [LeetCode] 857. Minimum Cost to Hire K WorkersLeetCode
- [LeetCode] 671. Second Minimum Node In a Binary TreeLeetCode
- LeetCode | 153. Find Minimum in Rotated Sorted ArrayLeetCode
- [LeetCode] 3096. Minimum Levels to Gain More PointsLeetCodeAI
- [LeetCode] 2406. Divide Intervals Into Minimum Number of GroupsLeetCodeIDE
- 【Leetcode】453. Minimum Moves to Equal Array ElementsLeetCode
- LeetCode: Two sum(兩數之和)LeetCode
- [LintCode/LeetCode] Check Sum of K PrimesLeetCode
- Leetcode 16 3Sum ClosestLeetCode
- LeetCode 259. Three Sum SmallerLeetCode