【题目】
给定整型数组arr,元素表示完成一幅画需要的时间,
给定整数num,表示画匠数,
每个画匠只能画连在一起的画作,所有画匠并行工作,
返回所有完成画作所需要的最少时间。
【例子】
public class demo {
public static void main(String[] args) {
int[] arr=new int[]{3,1,4};
System.out.println(Solution(arr,2));//4,第一个画匠画3和1,第二个画4,最少需要4
int[] arr1=new int[]{1,1,1,4,3};
System.out.println(Solution(arr1,3));//4,第一个画匠画111,第二个画4,第三个画3,最少需要4
}
【代码】
//画匠问题
//确定需要的画匠数(规定每个画匠画画的时间不能多于limit)
public static int getNeedNum(int[] arr,int limit){
int res=1;//画匠数
int stepSum=0;
for(int i=0;i<arr.length;i++){
if(arr[i]>limit){//某幅画工作量已经大于limit,退出该方法,调整limit
return Integer.MAX_VALUE;
}
stepSum+=arr[i];//同一个画匠的工作量累加
if(stepSum>limit){//直到超过limit,则当前的画应分给下一个画匠
res++;//画匠数加一
stepSum=arr[i];//重新开始累加工作量
}
}
return res;
}
public static int Solution(int[] arr,int num){
if(arr==null||arr.length==0||num<1){
throw new RuntimeException("err");
}
if(arr.length<num){//arr=[2,3],num=3,直接返回最大的arr[i],即每个画匠画一幅
int max=Integer.MIN_VALUE;
for(int i=0;i<arr.length;i++){
max=Math.max(max, arr[i]);
}
return max;
}
int minSum=0;
int maxSum=0;
for(int i=0;i<arr.length;i++){
maxSum+=arr[i];//完成所有画作的时间
}
while(minSum!=maxSum-1){//二分查找法,比较需要的画匠数和num,调整limit
int mid=(minSum+maxSum)/2;
if(getNeedNum(arr,mid)>num){
//需要的画匠数多了,说明mid小了,增大min
minSum=mid;
}
else{
maxSum=mid;//mid大了,减小max
}
}
return maxSum;
}