连续子数组之和大于等于target,总感觉可以用前缀和做,于是就写了个
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int len=nums.size(),ans=21474836;
vector<int> arr(len);
arr[0]=nums[0];
if(arr[0]>=target){
return 1;
}
for(int i=1;i<len;i++){
arr[i]=arr[i-1]+nums[i];
if(arr[i]>=target){
ans=min(ans,i+1);
for(int j=0;j<i;j++){
if(arr[i]-arr[j]<target){
break;
}
else{
ans=min(ans,i-j);
}
}
}
}
return ans==21474836?0:ans;
}
};
交上去发现超时了,优化一下的话,可以用二分去搜索j的位置,就少去一个循环,修改如下:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int len=nums.size(),ans=21474836;
vector<int> arr(len);
arr[0]=nums[0];
if(arr[0]>=target){
return 1;
}
for(int i=1;i<len;i++){
arr[i]=arr[i-1]+nums[i];
if(arr[i]>=target){
int p=0,q=i;
while(p<q){
int mid=p+(q-p)/2;
if(arr[i]-arr[mid]>=target){
p=mid+1;
}
else{
q=mid;
}
}
ans=min(ans,i-p+1);
}
}
return ans==21474836?0:ans;
}
};
瞄了眼答案,居然可以用双指针,我是**,但是双指针真香呐
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int len=nums.size(),ans=21474836;
int p=0,q=0,sum=0;
while(q<len){
sum+=nums[q++];
while(sum>=target){
ans=min(ans,q-p);
sum-=nums[p++];
}
}
return ans==21474836?0:ans;
}
};
最开始想的是排序后3个for循环穷举所有可能性,但是这么做肯定会超时,然后对它进行优化,能不能减去一个for循环呢,当然可以,当前两条边的长度已知,那么第三条边的最大长度也是可以知道的,那么就可以用二分在排好序的数组里查找,然后返回它的位置,那么比他小的元素肯定在左方,知道长度就可以得到有几种情况了,但是我没用二分,直接顺序查找也不会超时,摸了
○| ̄|_
class Solution {
public:
int triangleNumber(vector<int>& nums) {
if(nums.size()<3){
return 0;
}
sort(nums.begin(),nums.end());
int ans=0;
for(int i=0;i<nums.size()-2;i++){
int p=i+1,q=i+1;
while(p<nums.size()-1){
while(q+1<nums.size()&&nums[i]+nums[p]>nums[q+1]){
q++;
}
ans+=max(q-p,0);
p++;
}
}
return ans;
}
};