您的位置:首页 > 其它

[Leetcode] 209. Minimum Size Subarray Sum 解题报告

2017-06-19 14:28 387 查看
题目

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous 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.

click to show more practice.

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).

思路

1、Two Pointers:可以维护一个区间,使得在该区间内的和是小于s的。如果加上一个数之后区间的和大于s了,那么就从区间的左边开始删除元素,并且边删边判断是不是和依然大于s,更新结果。这种Two Pointers的时间复杂度是O(n),空间复杂度是O(1)。

2、二分查找法:这是从网上看到的解法,更加精妙一些。思想是用一个数组sums[i]来保存前i-1个数的和。这样可以保证数组的递增,然后从一个位置用二分查找大于sums[i] + s的值。之所以用sums[i] + s作为key来查找是因为这样就可以抛弃掉前i-1位数的和,查找一个从i开始的和大于s的区间(有没有很精妙?)。

代码

1、Two Pointers:

class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
if(nums.size() == 0) {
return 0;
}
int Min = INT_MAX, left = 0, sum = 0;
for(int i = 0; i< nums.size(); ++i) {
sum += nums[i];
while(sum >= s) {
Min = min(Min, i - left + 1);
sum -= nums[left++];
}
}
return Min == INT_MAX ? 0 : Min;
}
};
2、二分查找法:

class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int length = nums.size(), min_length = INT_MAX;
vector<int> sums(length + 1, 0);
for (int i = 1; i <= length; ++i) {
sums[i] = sums[i - 1] + nums[i - 1];
}
for (int i = 0; i < length; ++i) {
int pos = binarySearch(sums, i + 1, length, sums[i] + s);
if (pos == length + 1) {
continue;
}
min_length = min(min_length, pos - i); // update the min_length
}
return min_length == INT_MAX ? 0 : min_length;
}
private:
int binarySearch(vector<int> &sums, int left, int right, int key) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (sums[mid] < key) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
return left;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: