您的位置:首页 > 编程语言 > C语言/C++

Minimum Size Subarray Sum

2016-04-11 23:09 357 查看
题目:

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).
解答:
1.O(n)
 two points

用begins指针记录子串开头的位置,每次遍历一个字符,判断sum是否大于s,若是,则将该sum记录minlen中(sum<minlen);然后将begins+1,并将nums[begin]元素减去;若sum小于s,则 i+1, 且将其值加入sum中。以下为我的代码:

class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int begins = 0;
int len = nums.size();
if(len == 0)
return 0;
if(len==1){
if(nums[0]==s)
return 1;
else
return 0;
}
int minlen = len+1;
int sum = nums[0];
int i = 0;
while(i < len){
if(sum >= s){
int l = i - begins+1;
if(l < minlen)
minlen = l;
sum = sum-nums[begins];
++begins;
}else{
if(i+1>=len)
break;
sum = sum+nums[++i];
}
}
if(minlen == len+1)
return 0;
else
return minlen;
}
};


别人优秀的代码:(思路差不多)
O(n)

class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int n = nums.size(), start = 0, sum = 0, minlen = INT_MAX;
for (int i = 0; i < n; i++) {
sum += nums[i];
while (sum >= s) {
minlen = min(minlen, i - start + 1);
sum -= nums[start++];
}
}
return minlen == INT_MAX ? 0 : minlen;
}
};

2.O(nlogn) 
对于要求该复杂度,就要想到二分查找的方法。但是二分查找是对递增序列的,而原序列无法进行更改顺序,因此怎么找递增序列呢? 那就找从开头到每个元素的和的序列。如:  nums=[2,3,1,2,4,3]序列,则sums=[0,2,5,6,8,12,15].然后对于每个元素sums[i],找sums数组中大于sums[i]+s的值,用二分查找。找到后的位置j-i就是要求的长度。

这里调用别人的优秀的代码:

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