Retour aux défis
Moyen 0 résolus 0 % de réussite

Ordre de fin des tâches parallèles

Exécutez des tâches simultanément avec au plus k à la fois et indiquez l'ordre dans lequel elles se terminent.

Ce que vous allez apprendre

  • Exécuter des tâches avec une limite de parallélisme
  • Simuler le temps avec une file de priorité
  • Départager des tâches qui finissent ensemble

Problème

Avec async/await vous pouvez lancer plusieurs tâches et les laisser s'exécuter en même temps. Un SemaphoreSlim limite souvent combien peuvent tourner à la fois.

Les tâches numérotées de 0 à n − 1 prennent durations[i] unités de temps. Au temps 0, lancez autant de tâches que la limite le permet, dans l'ordre des indices. Chaque fois que des tâches se terminent, enregistrez-les (si plusieurs se terminent au même moment, le plus petit indice d'abord) et lancez immédiatement les prochaines tâches en attente, dans l'ordre des indices, pour remplir les emplacements libres.

Implémentez parallel_task_order(durations, limit).

Entrée

durations: La durée de chaque tâche.

limit: Le nombre maximum de tâches exécutées en même temps.

Sortie

Retournez les indices des tâches dans l'ordre où elles se terminent.

Contraintes

1 ≤ n ≤ 100,000

1 ≤ durations[i] ≤ 10^6; 1 ≤ limit ≤ n

Exemples

Exemple 1
Entrée :
limit = 2
durations = [4, 2, 3, 1]

Sortie attendue :
expected = [1, 0, 2, 3]
Entrée :
long long limit = 2;
std::vector<long long> durations = {4, 2, 3, 1};

Sortie attendue :
std::vector<long long> expected = {1, 0, 2, 3};
Entrée :
long limit = 2;
long[] durations = new long[] {4, 2, 3, 1};

Sortie attendue :
long[] expected = new long[] {1, 0, 2, 3};

Explication

Les tâches 0 et 1 démarrent. La tâche 1 se termine à 2 et la tâche 2 démarre (elle se termine à 5). La tâche 0 se termine à 4 et la tâche 3 démarre (elle se termine à 5). Les tâches 2 et 3 se terminent en même temps, le plus petit indice d'abord : [1, 0, 2, 3].

Exemple 2
Entrée :
limit = 3
durations = [3, 1, 2]

Sortie attendue :
expected = [1, 2, 0]
Entrée :
long long limit = 3;
std::vector<long long> durations = {3, 1, 2};

Sortie attendue :
std::vector<long long> expected = {1, 2, 0};
Entrée :
long limit = 3;
long[] durations = new long[] {3, 1, 2};

Sortie attendue :
long[] expected = new long[] {1, 2, 0};

Explication

Toutes les tâches s'exécutent en même temps et se terminent à 1, 2 et 3 : [1, 2, 0].

Comment l'aborder

Essayez d'abord seul, puis ouvrez les indices un par un.

Indice 1

Gardez les tâches en cours triées par heure de fin, puis par indice.

Indice 2

À chaque étape, sautez à la prochaine heure de fin et récupérez toutes les tâches qui finissent alors.

Indice 3

Remplissez les places libres avec les tâches en attente suivantes, par indice.

Complexité attendue

temps O(n log limit), espace supplémentaire O(limit)

Références

Ce défi a été adapté pour CodeUtility. Suivez l'énoncé et les contraintes ci-dessus.

Apprenez des autres

Solutions de la communauté

Aucune solution publiée pour l'instant. Résolvez ce défi pour partager la première.