打卡第十六天~
题目描述
- 有点阅读题的意思,可以结合例子理解一下题干~
代码 && 思路
1. 直白的 ac 做法 O(n)、O(n)
- 同样是 O(n) 复杂度,比方法2慢了不少= =,不过胜在容易想~
- wait[i]:记录 i 的等待冷却时间
- counts[i]:记录 i 的剩余任务数量
- 设计思路很简单,每次都选取当前不在冷却的、数量最多的任务,没有就待命即可
class Solution {
public int leastInterval(char[] tasks, int n) {
// 按照顺序来,max 的先来
int taskNums = tasks.length;
int[] counts = new int[26];
for(char c : tasks) {
counts[c - 'A']++;
}
int[] wait = new int[26];
int time = 0;
while(taskNums != 0) {
int index = chooseTask(counts, wait);
// 不待命的情况
if(index != -1) {
// System.out.println("选择" + (char)('A' + index));
counts[index]--;
taskNums--;
}
else {
// System.out.println("待命");
}
updateWait(wait, index, n);
time++;
}
return time;
}
public void updateWait(int[] wait, int index, int n) {
for(int i = 0; i < 26; i++) {
if(wait[i] < 0) {
wait[i]++;
}
}
if(index != -1) {
wait[index] = -n;
}
}
public int chooseTask(int[] counts, int[] wait) {
int index = -1;
int max = Integer.MIN_VALUE;
for(int i = 0; i < 26; i++) {
// 未冷却,且存在的最大值
if(wait[i] == 0 && counts[i] > max && counts[i] > 0) {
max = counts[i];
index = i;
}
}
return index;
}
}
2. 桶排思想的做法 O(n)、O(n)
- 参考了这篇题解的做法
- 步骤一:counts[ ] 记录各个任务的数量,维护最多任务数 maxTimes
- 步骤二:找到拥有 maxTiems 的任务种类数 maxTaskCounts
- 步骤三:根据公式计算结果:(maxTimes - 1) * (n + 1) + maxTaskCounts,如果公式结果小于 tasks.length,则选 tasks.length,否则选公式结果。
- 原理相关:直接看上面链接的题解吧,结合图片方便理解,我这里就不误人子弟了= =
- 关键点:
- 步骤三对应两种情况:有待命、无待命。
- 最后一趟无需再等待 n
class Solution {
public int leastInterval(char[] tasks, int n) {
// 桶排思想
// 1. 先找到 maxTimes
int maxTimes = 0;
int[] counts = new int[26];
for(char c : tasks) {
counts[c - 'A']++;
maxTimes = Math.max(maxTimes, counts[c - 'A']);
}
// 2. 找到并列 maxTimes 的字符数 maxTaskCounts
int maxTaskCounts = 0;
for(int num : counts) {
if(num == maxTimes) {
maxTaskCounts++;
}
}
// 3. 返回 task.length || (maxTimes - 1) * (n + 1) + maxTaskCounts
return Math.max(tasks.length, (maxTimes - 1) * (n + 1) + maxTaskCounts);
}
}
二刷
- 诶嘿,二刷终于是有了更好理解了,对于最后一行的return:
- 如果说数量足够多,那么就相当于无空闲时间,直接取最大的 task.length 即可
- 如果说数量不够,那么 length 铁定不能取,同时也肯定小于有空闲公式的值。
- 因此总的来说,得 max !
class Solution {
public int leastInterval(char[] tasks, int n) {
int maxRow = 0;
int[] counts = new int[26];
for(char c : tasks) {
counts[c - 'A']++;
maxRow = Math.max(counts[c - 'A'], maxRow);
}
int maxCol = 0;
for(int element : counts) {
if(element == maxRow) {
maxCol++;
}
}
return Math.max(tasks.length, (maxRow - 1) * (n + 1) + maxCol);
}
}