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.
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).
Credits:
Special thanks to @Freezen for adding this problem and creating all test cases.
这道题给定了我们一个数字,让我们求子数组之和大于等于给定值的最小长度,跟之前那道 Maximum Subarray 最大子数组有些类似,并且题目中要求我们实现O(n)和O(nlgn)两种解法,那么我们先来看O(n)的解法,我们需要定义两个指针left和right,分别记录子数组的左右的边界位置,然后我们让right向右移,直到子数组和大于等于给定值或者right达到数组末尾,此时我们更新最短距离,并且将left像右移一位,然后再sum中减去移去的值,然后重复上面的步骤,直到right到达末尾,且left到达临界位置,即要么到达边界,要么再往右移动,和就会小于给定值。代码如下:
思路
这道题需要比较巧妙的思考,不能直接蛮干,比如说移动窗口,再更新它的窗口最小长度;或者先计算累计和,通过加上给定的值,去得到窗口信息,再更新最小长度。
实现
移动窗口
// O(n)
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
if (nums.empty()) return 0;
int left = 0, right = 0, sum = 0, len = nums.size(), res = len + 1;
while (right < len) {
while (sum < s && right < len) {
sum += nums[right++];
}
while (sum >= s) {
res = min(res, right - left);
sum -= nums[left++];
}
}
return res == len + 1 ? 0 : res;
}
};
同样的思路,换另外一种写法
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int res = INT_MAX, left = 0, sum = 0;
for (int i = 0; i < nums.size(); ++i) {
sum += nums[i];
while (left <= i && sum >= s) {
res = min(res, i - left + 1);
sum -= nums[left++];
}
}
return res == INT_MAX ? 0 : res;
}
};
二分法
// O(nlgn)
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;
}
};
这个解法要用到二分查找法,思路是,我们建立一个比原数组长一位的sums数组,其中sums[i]表示nums数组中[0, i - 1]的和,然后我们对于sums中每一个值sums[i],用二分查找法找到子数组的右边界位置,使该子数组之和大于sums[i] + s,为什么要加上s呢,因为前面我们已经计算出了加上数组前面的和,那么我们只需要判断当前的值加上s等于后面的哪个值,就可以得出后面的值的下标,其实那个s就是前面和后面之间的原数组的值的和,然后我们更新最短长度的距离即可。
或者不需要新加一个函数
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int res = INT_MAX, n = nums.size();
vector<int> sums(n + 1, 0);
for (int i = 1; i < n + 1; ++i) sums[i] = sums[i - 1] + nums[i - 1];
for (int i = 0; i < n; ++i) {
int left = i + 1, right = n, t = sums[i] + s;
while (left <= right) {
int mid = left + (right - left) / 2;
if (sums[mid] < t) left = mid + 1;
else right = mid - 1;
}
if (left == n + 1) break;
res = min(res, left - i);
}
return res == INT_MAX ? 0 : res;
}
};
总结
看来并不能直接看别人的说的去实现,还是要自己去理解才行,每个人有每个人自己的理解。
Minimum Size Subarray Sum 最短子数组之和的更多相关文章
- [LeetCode] Minimum Size Subarray Sum 最短子数组之和
Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...
- [LeetCode] 209. Minimum Size Subarray Sum 最短子数组之和
Given an array of n positive integers and a positive integer s, find the minimal length of a contigu ...
- [LintCode] Continuous Subarray Sum 连续子数组之和
Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your cod ...
- lintcode :continuous subarray sum 连续子数组之和
题目 连续子数组求和 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.(如果两个相同的答案,请返回其中任意一个) 样例 给定 [-3, ...
- leetcode面试准备:Minimum Size Subarray Sum
leetcode面试准备:Minimum Size Subarray Sum 1 题目 Given an array of n positive integers and a positive int ...
- 领扣-209 长度最小的子数组 Minimum Size Subarray Sum MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- [LeetCode] Minimum Size Subarray Sum 解题思路
Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...
- [LintCode] Minimum Size Subarray Sum 最小子数组和的大小
Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...
- 【刷题-LeetCode】209. Minimum Size Subarray Sum
Minimum Size Subarray Sum Given an array of n positive integers and a positive integer s, find the m ...
随机推荐
- Shell-输入密码转换为*
Code: read -p "请输入使用者都名称:" USER echo -e "请输入使用者密码: \c" while : ;do char=` #这里是反引 ...
- SQl 跨服务器查询脚本示例
1.采用OPENDATASOURCE select top 10 *from OPENDATASOURCE('SQLOLEDB','Data Source=IP地址;User ID=连接用户名称;Pa ...
- [转载]Windows服务编写原理及探讨(3)
(三)对服务的深入讨论之下 现在我们还剩下一个函数可以在细节上讨论,那就是服务的CtrlHandler函数. 当调用RegisterServiceCtrlHandler函数时,SCM得到并保存这个回调 ...
- Python模块:Random(未完待续)
本文基于Python 3.6.5的官文random编写. random模块简介 random为各种数学分布算法(distributions)实现了伪随机数生成器. 对于整数,是从一个范围中均匀选择(u ...
- day04作业
1.for(初始化表达式:条件表达式:循环后的操作表达式){ 循环体: } class Test_Sum { public static void main(String[] args) { int ...
- thinkphp模版常量替换机制
- ZOJ 3469 Food Delivery(区间DP好题)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4255 题目大意:在x轴上有n个客人,每个客人每分钟增加的愤怒值不同. ...
- the server ssl certificate failed to verify
很久没上传项目之后,远程端断开联系 如果是git,就git clone,重新把项目拉下来. svn的话,就svn ls,拉下项目.
- Sql Server2005 Transact-SQL 新兵器学习总结之-排名函数
Transact-SQL提供了4个排名函数: rand() , dense_rand() , row_number() , ntile() 下面是对这4个函数的解释:rank() 返回结果集的分区内每 ...
- 我常用的 Python 调试工具 - 博客 - 伯乐在线
.ckrating_highly_rated {background-color:#FFFFCC !important;} .ckrating_poorly_rated {opacity:0.6;fi ...