【LeetCode】第1723题——完成所有工作的最短时间(难度:困难)

【LeetCode】第1723题——完成所有工作的最短时间(难度:困难)

  • 题目描述
  • 解题思路
  • 代码详解
  • 注意点

题目描述

给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间。

请你将这些工作分配给 k 位工人。所有工作都应该分配给工人,且每项工作只能分配给一位工人。工人的 工作时间 是完成分配给他们的所有工作花费时间的总和。请你设计一套最佳的工作分配方案,使工人的 最大工作时间 得以 最小化 。

返回分配方案中尽可能 最小 的 最大工作时间 。

  1. 示例 1:
    输入:jobs = [3,2,3], k = 3
    输出:3
    解释:给每位工人分配一项工作,最大工作时间是 3 。

  2. 示例 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 。

提示:
1 <= k <= jobs.length <= 12
1 <= jobs[i] <= 107

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-minimum-time-to-finish-all-jobs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

此题难以直接找出正确答案(当然可以用dp),不过可以发现,若数值n可以作为“工人的最大工作时间”,那么比n大的数就完全可以不用考虑了。因此可以用二分查找法找出正确答案(找的过程是不断试错的过程)。下限是工作时长最长的值,上限是所有工作时长的和。

那么如何确定n是否可以作为“工人的最大工作时间”呢?我们采取回溯+剪枝的策略。开辟一个长度为k的数组,表示每个工人的总工作时长。

工作的分配顺序是从用时多往用时少,每份工作均先从0号员工开始尝试分配,若满足“工人的最大工作时间”要求则尝试给当前员工分配工作,并继续递归下去,若后续递归中无法满足要求则需回溯,若回溯至递归开头仍然无法寻找到满足要求的方案,说明当前“工人的最大工作时间”过短,二分法的左节点便更新为当前“工人的最大工作时间”+1。若成功找到分配方案,说明当前“工人的最大工作时间”是可行的,答案一定小于等于此时间,二分法的右节点便更新为当前“工人的最大工作时间”,继续二分查找下去。

代码详解

class Solution {
   
    public int minimumTimeRequired(int[] jobs, int k) {
   
        Arrays.s

你可能感兴趣的:(LeetCode题解,剪枝,回溯,二分法,leetcode,java)