题目:2071. 你可以安排的最多任务数目
思路:二分查找+贪心,题目的意思就是找到最大可以完成的任务数量l,对于这个任务数量l,一定满足,任务里最小的l个,和工人里最大的l个,它们之间满足条件。那么我们就用二分查找来找到最大的这个l,这里的时间复杂度为0(logn)。对于check函数,时间复杂度是0(nlogn)。最终的时间复杂度为0(nlogn * logn )
check函数里的贪心:我们对任务的难度升序判断,对于最小的任务,那么我们肯定是希望最小力量的工人来完成,如果不能完成,那肯定就需要吃药啦。如果吃药可以完成这个最小的任务,我们就查找吃完药后,这个工人可以完成的最大任务,这里就用到了贪心的思想。
class Solution {
public:
bool check(int u,vector<int>& tasks, vector<int>& workers, int pills, int strength){
bool flag=true;
vector<int> ta,wo;
int m=workers.size();
// 贪心
for(int i=0;i<u;i++){
ta.push_back(tasks[i]);
wo.push_back(workers[m-u+i]);
}
int i=0,j=0;
while(j<u){
if(ta[i]<=wo[j]){
i++,j++;
}else if(pills &&ta[i]<=wo[j]+strength){
//吃药后,选最大可以解决的任务
ta.erase(upper_bound(ta.begin()+i,ta.end(),wo[j]+strength)-1);
pills--;
j++;
}else{
flag=0;
break;
}
}
return flag;
}
int maxTaskAssign(vector<int>& tasks, vector<int>& workers, int pills, int strength) {
sort(tasks.begin(),tasks.end());
sort(workers.begin(),workers.end());
int n=tasks.size(),m=workers.size();
int l=0,r=min(n,m);
//二分查找
while(l<r){
int mid=(l+r+1)/2;
if(check(mid,tasks,workers,pills,strength))l=mid;
else r=mid-1;
}
return l;
}
};
JAVA版本:
class Solution {
int findd(List<Integer> ta,int u){
int l=0,r=ta.size()-1;
while(l<=r){
int mid=(l+r)/2;
if(ta.get(mid)<=u) l=mid+1;
else r=mid-1;
}
return l-1;
}
boolean check(int u,int[] tasks, int[] workers, int pills, int strength){
boolean flag=true;
List<Integer> ta=new ArrayList<Integer>();
List<Integer> wo=new ArrayList<Integer>();
int m=workers.length;
for(int i=0;i<u;i++){
ta.add(tasks[i]);
wo.add(workers[m-u+i]);
}
int i=0,j=0;
while(j<u){
if(ta.get(i)<=wo.get(j)){
i++;
j++;
}else if(pills!=0 &&ta.get(i)<=wo.get(j)+strength){
ta.remove(findd(ta,wo.get(j)+strength));
pills--;
j++;
}else{
flag=false;
break;
}
}
return flag;
}
public int maxTaskAssign(int[] tasks, int[] workers, int pills, int strength) {
Arrays.sort(tasks);
Arrays.sort(workers);
int n=tasks.length,m=workers.length;
int l=0,r=Math.min(n,m);
while(l<r){
int mid=(l+r+1)/2;
if(check(mid,tasks,workers,pills,strength))l=mid;
else r=mid-1;
}
return l;
}
}