你可以安排的最多任务数目

题目链接

你可以安排的最多任务数目

题目描述



注意点

  • 1 <= n, m <= 5 * 10^4
  • 0 <= pills <= m
  • 0 <= tasks[i], workers[j], strength <= 10^9
  • 每个工人只能完成一个任务
  • 每个工人最多只能使用一片药丸

解答思路

  • 参照题解使用二分查找 + 贪心算法解决本题
  • 二分查找的思想是找到可以安排的最多任务数目k,初始认为最少能完成的任务数目是0,最多能完成的任务数目是Math.min(tasks.length, workers.length),根据中间值不断二分找到k
  • 贪心算法的思想是假设可以安排的最多任务数目一定是mid,那么应该安排力量最大的k个工人完成需要力量最小的k个任务,具体应该怎么分配任务?从最大的任务task遍历:
    • 如果此时力量最大的工人能够完成task,则贪心地认为该工人直接完成task
    • 如果此时力量最大的工人无法完成task,且还有药丸,则贪心地认为加上药丸后能够完成task的工人中力量最小的工人完成task
    • 如果此时力量最大的工人无法完成task,且没有药丸,则说明无法安排k个工人完成k个任务

代码

class Solution {
    public int maxTaskAssign(int[] tasks, int[] workers, int pills, int strength) {
        Arrays.sort(tasks);
        Arrays.sort(workers);
        int min = 0;
        int max = Math.min(tasks.length, workers.length);
        while (min < max) {
            int mid = (min + max + 1) >> 1;
            boolean b = midTaskAssign(tasks, workers, pills, strength, mid);
            if (b) {
                min = mid;
            } else {
                max = mid - 1;
            }
        }
        return min;
    }

    public boolean midTaskAssign(int[] tasks, int[] workers, int pills, int strength, int mid) {
        Deque<Integer> dq = new ArrayDeque<>();
        int idx = workers.length - 1;
        // 假设必定能完成k个任务,力量最大的k个工人完成需要力量最小的k个任务
        // 从k个任务中需要力量最大的任务开始遍历
        for (int i = mid - 1; i >= 0; i--) {
            int task = tasks[i];
            // 将所有加上药丸后能完成tasks[i]的工人都添加到队列中
            while (idx >= 0 && workers[idx] + strength >= task) {
                dq.offerFirst(workers[idx]);
                idx--;
            }
            // 没有工人加上药丸可以完成task
            if (dq.isEmpty()) {
                return false;
            }
            if (dq.peekLast() >= task) {
                // 力量最大的工人不需要药丸可以直接完成task,贪心地认为该工人直接完成task即可(此时task需要的力量最大)
                dq.pollLast();
            } else if (pills == 0) {
                // 没有药丸
                return false;
            } else {
                // 贪心地认为加上药丸后能够完成task的工人中力量最小的工人完成task
                dq.pollFirst();
                pills--;
            }
        }
        return true;
    }
}

关键点

  • 二分查找的思想
  • 贪心算法的思想
  • 怎么找到加上药丸后能够完成task的工人中力量最小的工人
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值