LCP 12. 小张刷题计划
思路:二分查找。T的最小值为0,最大值为数组time的元素之和sum(最大就是10^9)。通过二分到这个区间0~sum进行查找,时间复杂度为0(logn)。check()函数所花的时间为0(n)。总的时间复杂度为0(nlogn)。细节看注释。
class Solution {
public:
bool check(int u,vector<int> & time,int &m){
int ans=1;//记录当前画的天数,答案为0的已经在最开始处理过了(n<=m)
int sum=0;//记录当前选中区间的总和
int mx=0;//记录当前选中区间的最大值
for(int i=0;i<time.size();i++){
mx=max(mx,time[i]);
if(time[i]+sum<=u+mx){
//当前区间减去最大值还是<=u
sum+=time[i];
}else{
//不能再加入这个数time[i],需要另外构建一个区间
ans++;
sum=time[i];
mx=time[i];
}
}
//cout<<"u:"<<u<<"-"<<ans<<endl;
return ans<=m;
}
int minTime(vector<int>& time, int m) {
int n=time.size();
//为0的情况
if(n<=m) return 0;
//求出总和sum
int sum=0;
for(int i=0;i<n;i++){
sum+=time[i];
}
//进行二分查找
int l=0,r=sum;
while(l<r){
int mid=(l+r)/2;
if(check(mid,time,m)){
r=mid;
}else{
l=mid+1;
}
}
return l;
}
};