Programador de tareas — Leetcode 621

Dec 19 2022
Enlace del problema original: https://leetcode.com/problems/task-scheduler/description/ En este problema, se nos pide que calculemos el tiempo mínimo necesario para terminar todas las tareas (que toman 1 unidad de tiempo cada una) en una matriz , dado un tiempo de recuperación de n unidades entre las mismas tareas (que se pueden llenar con otras tareas diferentes).

Enlace del problema original:https://leetcode.com/problems/task-scheduler/description/

En este problema, se nos pide que calculemos el tiempo mínimo necesario para terminar todas las tareas (que toman 1 unidad de tiempo cada una) en una matriz, dado un tiempo de recuperación de n unidades entre las mismas tareas (que se pueden completar con otras diferentes). Tareas).

Podemos encontrar la respuesta directamente usando matemáticas. La intuición detrás de mi solución es encontrar la frecuencia máxima de cualquier tarea y la cantidad de tales tareas con la frecuencia máxima. Luego, distribuimos el resto de las tareas de manera uniforme en cada ciclo y rellenamos cada ciclo con unidades de tiempo de inactividad si es necesario. Cada variable tiene un comentario explicando su significado.

class Solution {

    public int leastInterval(char[] tasks, int n) {
        if (n == 0) {
            return tasks.length;
        }
        Map<Character, Integer> taskMap = new HashMap<>();
        // highest frequency of the same task appearing
        int maxFrequency = 0;
        for (char task : tasks) {
            taskMap.put(task, taskMap.getOrDefault(task, 0) + 1);
            maxFrequency = Math.max(taskMap.get(task), maxFrequency);
        }

        // number of such max frequency tasks
        int maxFreqTasks = 0;
        for (char task : taskMap.keySet()) {
            if (taskMap.get(task) == maxFrequency) {
                maxFreqTasks++;
            }
        }

        // rest of the tasks
        int nonMaxFreqTasks = tasks.length - (maxFreqTasks * maxFrequency);
        // rest of the distributed tasks on each cycle
        int cycleLength = maxFrequency > 1 ? (nonMaxFreqTasks / (maxFrequency - 1)) : 0;
        // extra tasks distributed to the first few cycles if any
        int remaining = maxFrequency > 1 ? (nonMaxFreqTasks % (maxFrequency - 1)) : 0;

        // total length of each cycle (minus remaining)
        int cycle = maxFreqTasks + cycleLength;
        int idle = 0;
        // distribute idles if needed
        if (cycle + 1 <= n && remaining > 0) {
            idle += ((maxFrequency - 1) * (n - cycle));
        } else if (cycle <= n && remaining == 0) {
            idle += ((maxFrequency - 1) * (n - cycle + 1));
        }
        // add extra idles for the cycles that didn't get the "remaining" tasks
        if (remaining > 0 && cycle <= n) {
            idle += (maxFrequency - 1 - remaining);
        }
        return tasks.length + idle;
    }
}