您的位置:首页 > 其它

209. Minimum Size Subarray Sum

2017-12-25 11:09 337 查看
1、题目描述

输入一个正整数数组和整数s,找出数组中最短的序列,它的序列和大于或等于s。

2、思路

方法1:Two Pointers。

声明一个用于记录序列和的变量sum,一个用于记录序列左端的变量left。

遍历数组,在sum上加上当前数字,如果sum小于s,则继续向右扩充sum,使其增长;

若sum已经大于或等于s,则努力地向右移动left,即从sum中减掉尽可能多的左边的值,令sum仍大于或等于s;

更新left和sum,更新ans。

时间复杂度O(n),空间复杂度O(1)。

方法2:Binary Search.

更新数组,让数组的每个元素,都是前面所有元素和该元素的和。

对合法的序列长度进行二分查找。

l = 1, r = 数组长度,如果数组中有mid长度的序列和大于等于s,则令r = mid;

反之,令l = mid+1.

时间复杂度O(nlogn),空间复杂度O(1)。

方法3:Binary Search.
更新数组,让数组的每个元素,都是前面所有元素和该元素的和。

对于用每个元素开头的序列,用二分查找的方式找到最短的序列,使得序列和大于等于s。

时间复杂度O(nlogn),空间复杂度O(1)。

3、代码

方法1:

int minSubArrayLen(int k, vector<int>& nums) {
int n = nums.size();
int ans = INT_MAX;
int sum=0;
int left = 0;
for(int i=0;i<n;i++){
sum+=nums[i];
while(sum-nums[left]>=k){
sum-=nums[left];
left++;
}
if(sum>=k)
ans=min(ans,i-left+1);
}
if(ans==INT_MAX) return 0;
return ans;
}


方法2:

int minSubArrayLen(int k, vector<int>& nums) {
int n = nums.size();
for(int i=1;i<n;i++){
nums[i]+=nums[i-1];
}
if(n==0||nums[n-1]<k) return 0;
int l = 1 , r = n;
while(l<r){
int mid = l + (r - l) / 2;
if(isok(nums,k,mid))
r = mid;
else
l = mid+1;
}
return l;
}
bool isok(vector<int> nums, int k, int mid){
if(nums[mid-1]>=k) return true;
for(int i = mid;i <nums.size();i++){
if(nums[i]-nums[i-mid]>=k)
return true;
}
return false;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息