Minimum Size Subarray Sum
来自 <https://leetcode.com/problems/minimum-size-subarray-sum/>
Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn't one, return 0 instead.
For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.
More practice:
If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).
Credits:
Special thanks to @Freezen for adding this problem and creating all test cases.
题目解读:
给定一个长度为n的正整数数组和和一个正整数,找出一个长度最短的子数组,使子数组元素之和sum ≥ s。如果这样的子数组不存在,则返回0.
例如:给定的数组为[2,3,1,2,4,3]和 s=7。则子数组[4,3]的长度最小。
解析:
解法一:从前向后遍历数组,设置两个指针i,j ,在开始时两个指针指向相同的位置。遍历数组时,一个指针i首先保持不动,另外一个指针j向后移动并记录并记录指针i和j之间数组元素的和sum,如果sum<s,则j继续向后移动。如果sum>=s。则记录length=j-i,看其是否小于minlength, 如果小于,则minlength=length;否则minlength保持不变。此时i和j再同时指向i的下一个位置,依次循环。主要利用滑动窗口的思想。
图片摘自:http://blog.csdn.net/lisonglisonglisong/article/details/45666975
解法二:
摘自http://www.cnblogs.com/tonyluis/p/4564076.html
在方法一中,保持前面的指针不变,让后边的指针移动。在方法二中,维护一个左边界,让右边的正常移动。
解法三:分治法
摘自http://www.huhaoyu.com/leetcode-minimum-size-subarray-sum/
解法一代码:
Public int minSubArrayLen(int s, int[] nums) { int sum = 0; int minlength = nums.length; int length = 0; for(int i=0; i<nums.length; i++) { sum += nums[i]; int j=0; for(j=i+1; j<nums.length; j++ ) { if(sum >= s) { length = j-i; break; } else { sum += nums[j]; } } if(j==nums.length && sum >= s) { length = j-i; } if(minlength > length) { minlength = length; } sum = 0; } if(minlength != nums.length) { return minlength; } else { return 0; } }
解法一性能:
解法二代码:
public int minSubArrayLen(int s, int[] nums) { int i=0; int left = 0; int minLength = nums.length; int sum = 0; int length = 0; for(i=0; i<nums.length; i++) { sum += nums[i]; while(sum >= s) { length = i-left+1; //minLength = Math.min(minLength, i-left+1); if(minLength > length) { minLength = length; } sum -= nums[left++]; } } //return minLength==nums.length?0:minLength; if(minLength == nums.length) { return 0; } else { return minLength; } }
解法二性能:
解法三代码:(仅作参考,提交不成功,但是个很好的思想)
class Solution { public: int MAX_INT = 999999999; int minSubArrayLen(int s, vector<int>& nums) { if (!nums.size()) return 0; return findMinLen(s, nums, 0, nums.size() - 1); } int findMinLen(int s, vector<int>& nums, int bottom, int top) { if (top == bottom) return nums[top] >= s ? 1 : 0; int mid = (bottom + top) / 2; int left = mid, right = mid + 1, sum = 0, len; while (sum < s && (right <= top || left >= bottom)) { if (right > top) { sum += nums[left]; --left; } else if (left < bottom) { sum += nums[right]; ++right; } else if (nums[left] > nums[right]) { sum += nums[left]; --left; } else { sum += nums[right]; ++right; } } if (sum >= s) { len = right - left - 1; int leftLen = findMinLen(s, nums, bottom, mid); int rightLen = findMinLen(s, nums, mid + 1, top); return minValue(leftLen, rightLen, len); } else { return 0; } } int minValue(int x, int y, int z) { if (!x) x = MAX_INT; if (!y) y = MAX_INT; if (x <= y && x <= z) return x; if (y <= x && y <= z) return y; return z; } };
来自 <http://www.huhaoyu.com/leetcode-minimum-size-subarray-sum/>