leetcode 621.Task Scheduler

本文深入探讨了CPU任务调度算法,特别是在存在冷却间隔约束的情况下,如何优化任务执行顺序以减少闲置时间。通过实例分析,解释了如何计算完成所有任务所需的最小时间周期,以及在特定条件下如何调整计算公式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a char array representing tasks CPU need to do. It contains capital letters A to Z where different letters represent different tasks. Tasks could be done without original order. Each task could be done in one interval. For each interval, CPU could finish one task or just be idle.

However, there is a non-negative cooling interval n that means between two same tasks, there must be at least n intervals that CPU are doing different tasks or just be idle.

You need to return the least number of intervals the CPU will take to finish all the given tasks.

Example:

Input: tasks = [“A”,“A”,“A”,“B”,“B”,“B”], n = 2
Output: 8
Explanation: A -> B -> idle -> A -> B -> idle -> A -> B.

给出一个tasks的数组,代表不同的task,一个周期CPU可以选择处理一个task,也可以闲置
而且处理相同的task的时候,中间必须有n次闲置

比如上面例子中一个A到下一个A之间必须有n=2次闲置

思路:
为了不闲置,尽量每次处理不同的task
比如上面的例子,把不同的task先分组放在一起,一次处理一个由不同task组成的组,在这个组内就不需要闲置
而且每组的顺序应该是一样,这样才能保证相同的task间隔最远

AB AB AB

这样相同的A之间隔了一个B,但是题中要求n=2
也就是两个A之间需要间隔两个周期
因为少了一个,所以补一个idle(闲置),可以看到最后的一组后面是不需要补的
AB(idle)AB(idle)AB

而能留到最后一组的就是frequency最高的几个task
比如[A,A,A,A,B,B,C]
分组后(假设n=2)
ABC AB(idle) A(idle)(idle) A

可以看到需要的时间周期是由最大frequency的task决定的,由于最后一个不需要加idle
所以不看最后一个的时候,需要的时间周期是
(maxFrequency - 1) * (n + 1) //(n+1)是因为还要加上自身task

再加上最后一组,也就是最大frequency的task个数
(maxFrequency - 1) * (n - 1) + maxFrequencyNum

不过还有一种特殊情况,比如分组后task是ABC ABC,而n=1的情况
可以看到相同task间的间隔是>n的,但是如果按上述方法n=1进行计算
结果result就会比task的总个数小,这时候需要取
max(tasksNum, result)

//2ms
    public int leastInterval(char[] tasks, int n) {
        if (tasks == null || tasks.length == 0) {
            return 0;
        }
        
        if (n == 0) {
            return tasks.length;
        }
        
        int[] count = new int[26];
        int maxCount = 0;
        int res = 0;
        int sameFreq = 0;       
        
        for (int i = 0; i < tasks.length; i++) {
            count[tasks[i] - 'A'] ++;
        }
        
        for (int i = 0; i < count.length; i++) {
            if (count[i] > maxCount) {
            	maxCount = count[i];
            };
        }
        
        for (int i = 0; i < count.length; i++) {
            if (count[i] == maxCount) {
            	sameFreq ++;
            };
        }
        
        res = (maxCount - 1) * (n + 1) + sameFreq;
        
        return Math.max(tasks.length, res);
        
    }

用c++就会方便很多
count_if中用到lambda表达式,需要用到前面的max_count,所以放在[max_count]
lambda表达式中也需要加;
另外max比较的时候不能是int类型,所以res的类型是size_t

//48ms
class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
        vector<int> count(26, 0);
        
        for (int i = 0; i < tasks.size(); i++) {
            count[tasks[i] - 'A'] ++;
        }
        
        int max_count = *max_element(count.cbegin(), count.cend());
        int same_freq = count_if(count.cbegin(), count.cend(), 
                                 [max_count](int c){return c == max_count;});
        size_t res = (max_count - 1) * (n + 1) + same_freq;
        
        return max(tasks.size(), res);
    }
    
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值