LeetCode LCP 32. 批量处理任务

LCP 32. 批量处理任务

某实验室计算机待处理任务以 [start,end,period] 格式记于二维数组 tasks,表示完成该任务的时间范围为起始时间 start 至结束时间 end 之间,需要计算机投入 period 的时长,注意:

  1. period 可为不连续时间
  2. 首尾时间均包含在内

处于开机状态的计算机可同时处理任意多个任务,请返回电脑最少开机多久,可处理完所有任务。

示例 1:

输入:tasks = [[1,3,2],[2,5,3],[5,6,2]]

输出:4

解释: tasks[0] 选择时间点 2、3; tasks[1] 选择时间点 2、3、5; tasks[2] 选择时间点 5、6; 因此计算机仅需在时间点 2、3、5、6 四个时刻保持开机即可完成任务。

示例 2:

输入:tasks = [[2,3,1],[5,5,1],[5,6,2]]

输出:3

解释: tasks[0] 选择时间点 2 或 3; tasks[1] 选择时间点 5; tasks[2] 选择时间点 5、6; 因此计算机仅需在时间点 2、5、6 或 3、5、6 三个时刻保持开机即可完成任务。

提示:

  • 2 <= tasks.length <= 10^5
  • tasks[i].length == 3
  • 0 <= tasks[i][0] <= tasks[i][1] <= 10^9
  • 1 <= tasks[i][2] <= tasks[i][1]-tasks[i][0] + 1

解法1:贪心 + 二分查找 + 栈

同类题目详解:LeetCode 2589. 完成所有任务的最少时间-CSDN博客

Java版:

class Solution {
    public int processTasks(int[][] tasks) {
        Arrays.sort(tasks, (a, b) -> a[1] - b[1]);
        List<int[]> stack = new ArrayList<>();
        stack.add(new int[]{-1, -1, 0});
        for (int[] task : tasks) {
            int start = task[0];
            int end = task[1];
            int duration = task[2];
            int k = binarySearch(stack, start);
            duration -= stack.get(stack.size() - 1)[2] - stack.get(k)[2];
            if (start <= stack.get(k)[1]) {
                duration -= stack.get(k)[1] - start + 1;
            }
            if (duration <= 0) {
                continue;
            }

            while (stack.size() > 1 && end - stack.get(stack.size() - 1)[1] <= duration) {
                duration += stack.get(stack.size() - 1)[1] - stack.get(stack.size() - 1)[0] + 1;
                stack.remove(stack.size() - 1);
            }
            stack.add(new int[]{end - duration + 1, end, stack.get(stack.size() - 1)[2] + duration});
        }
        return stack.get(stack.size() - 1)[2];
    }

    private int binarySearch(List<int[]> stack, int target) {
        int l = 0;
        int r = stack.size() - 1;
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if (stack.get(mid)[0] < target) {
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        return r;
    }
}

Python3版:

class Solution:
    def processTasks(self, tasks: List[List[int]]) -> int:
        tasks.sort(key = lambda x: x[1])
        stack = [[-1, -1, 0]]
        for start, end, duration in tasks:
            k = bisect_left(stack, start, key = lambda x: x[0])
            duration -= stack[-1][2] - stack[k - 1][2]
            if start <= stack[k - 1][1]:
                duration -= stack[k - 1][1] - start + 1
            if duration <= 0:
                continue 
            
            while len(stack) > 1 and end - stack[-1][1] <= duration:
                duration += stack[-1][1] - stack[-1][0] + 1
                stack.pop()
            stack.append([end - duration + 1, end, stack[-1][2] + duration])
        return stack[-1][2]

复杂度分析

  • 时间复杂度:O(nlogn),其中 n 为 tasks 的长度。
  • 空间复杂度:O(n)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值