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
the subarray
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中。以下为我的代码:
别人优秀的代码:(思路差不多)
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;
}
};
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;
}
};
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性