1723. 完成所有工作的最短时间 javascript
题目:
给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间。
请你将这些工作分配给 k 位工人。所有工作都应该分配给工人,且每项工作只能分配给一位工人。工人的 工作时间 是完成分配给他们的所有工作花费时间的总和。请你设计一套最佳的工作分配方案,使工人的 最大工作时间 得以 最小化 。
返回分配方案中尽可能 最小 的 最大工作时间 。
example:
输入:jobs = [3,2,3], k = 3
输出:3
解释:给每位工人分配一项工作,最大工作时间是 3 。
示例 2:
输入:jobs = [1,2,4,7,8], k = 2
输出:11
解释:按下述方式分配工作:
1 号工人:1、2、8(工作时间 = 1 + 2 + 8 = 11)
2 号工人:4、7(工作时间 = 4 + 7 = 11)
最大工作时间是 11 。
思路: javascript
但当提交代码后,发现存在问题,对于[12,13,14,17,25] 3 的情况不正确。
代码: 错误代码
var minimumTimeRequired = function(jobs, k) {
let len = jobs.length;
// 如果jobs的长度小于等于工人数的话,那么就最小的最大工作时间就是数组的最大值
if(len<=k) return Math.max.apply(null,jobs);
// 否则的话就需要寻找jobs中最小的组合
let sum = eval(jobs.join('+'))
// 向上取整
let ave = Math.ceil(sum / k);
// 向下取整
let ave_b = Math.floor(sum / k);
if(k==2 & sum % k == 0) return ave;
// 根据工人数量k去创建一个全为0的数组,然后根据sum/k的值去进行后续判断
let time = new Array(k).fill(0);
time[0] = jobs[0]
jobs.splice(0,1)
// console.log('after',time)
// 如果ave-times[i]在jobs中存在,则time[i]+(ave-time[i])
for(let i=0;i<k;i++){
let sub = ave - time[i]
// console.log('sub',sub)
if(jobs.indexOf(sub) != -1){
time[i] += sub
jobs.splice(jobs.indexOf(sub),1)
// console.log('jobs-after',jobs)
}else if(jobs.indexOf(sub) == -1 & jobs.indexOf(ave_b - time[i])!=-1){
let temp_s = jobs.indexOf(ave_b - time[i])
// console.log(i,time[i],ave_b-time[i],jobs.indexOf(ave_b - time[i]))
time[i] += ave_b - time[i]
jobs.splice(temp_s,1)
// console.log('jobs-after',jobs)
}else{
time=time.concat(jobs);
jobs.splice(0,jobs.length);
}
}
// console.log('time-after',time)
// console.log('jobs-after',jobs)
return Math.max.apply(null,time);
};
以下是大佬的正确解法:
- 暴力求所有分配方式,然后计算最小值就好
- 回溯模板,然后剪枝(存在多个相同工作时间的工人,分配下一个工作时不需要重复尝试,都是一样的,剪掉)
- 当前已经有一个解的情况,工人分配完工作的时间超出这个解,肯定不是最优,剪掉
var minimumTimeRequired = function (jobs, k) {
// 记录每个工人的工作时间
var record = new Array(k).fill(0);
var min = Infinity;
function backtrack(index) {
// 得到一种分配方式,更新最优解
if (index >= jobs.length) {
min = Math.min(min, Math.max(...record));
return;
}
var cache = {};
// 尝试将工作分配给不同的工人
for (var i = 0; i < record.length; i++) {
// 剪枝,相同工作时间不需要再次尝试
var n = record[i];
if (cache[n]) continue;
cache[n] = 1;
// 剪枝,工作时间超过了当前的最优解
if (record[i] + jobs[index] > min) continue;
// 改变状态
record[i] += jobs[index];
// 递归
backtrack(index + 1);
// 回溯,还原状态
record[i] -= jobs[index];
}
}
backtrack(0);
return min;
};
学艺不精,还需努力💪