完成所有工作的最短时间

package cn.tiger.funny;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

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

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

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

示例 1:

输入: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 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-minimum-time-to-finish-all-jobs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 * @author jyuan
 *
 */
public class MinimumTimeRequired {
    public int minimumTimeRequired(int[] jobs, int k) {
        List<Integer> joblist = sort(jobs);
        int sum = sum(jobs);
        int[] k_sum = new int[k];
        int avg = joblist.get(0);
        if (avg < sum/k) {
            avg = sum/k;
        }

        while (!checkMinimumTime(joblist, k_sum, sum, avg)) {
            avg++;
        }
        
        return avg;
    }
    
    /**
     * 将数组转换成list,倒叙排列
     * @param jobs
     * @return
     */
    private List<Integer> sort(int[] jobs) {
        List<Integer> list = new ArrayList<>(jobs.length);
        for (int job : jobs) {
            list.add(job);
        }
        Collections.sort(list);
        Collections.reverse(list);
        return list;
    }
    
    /**
     * 求和
     * @param jobs
     * @return
     */
    private int sum(int[] jobs) {
        int sum = 0;
        for (int i : jobs) {
            sum += i;
        }
        return sum;
    }
    
    /**
     * 检查当前值是否满足完成工作的最小值
     * @param list
     * @param k_sum
     * @param sum
     * @param avg
     * @return
     */
    private boolean checkMinimumTime(List<Integer> list, int[] k_sum, int sum, int avg) {
        if(list.isEmpty()) {
            for (int i : k_sum) {
                System.out.println("---"+ i);
            }
            return true;
        }
        if (avg*k_sum.length < sum) {
            return false;
        }
        int biggest_num = list.get(0);
        for (int i=0; i<k_sum.length; i++) {
            if(k_sum[i]+biggest_num <= avg) {
                k_sum[i] = k_sum[i]+biggest_num;
                list.remove(0);
                boolean flag = checkMinimumTime(list, k_sum, sum, avg);
                if (flag) {
                    return true;
                }
                list.add(0, biggest_num);
                k_sum[i] = k_sum[i]-biggest_num;
                if(k_sum[i]==0) {
                    return false;
                }
            }
        }
        return false;
    }
    
    
//    public static void main(String[] args) {
//        MinimumTimeRequired a = new MinimumTimeRequired();
//        int[] jobs = {3,2,3,3,4,6,7,5,34,2,45,7,8,5,3,23,7,45,68,34,2,67,67,7,45,34,34};
//        System.out.println(a.sum(jobs));
//        System.out.println(a.minimumTimeRequired(jobs, 5));
//    }
}

想了一会没想到好的方法,用最笨的方法完成了题解。在性能方面应该还有优化的点,头胀懒得弄了。

 

posted @ 2021-01-15 16:52  预言2018  阅读(154)  评论(0)    收藏  举报