Ce défi passe d'un test d'admission à un cours de cybersécurité à numéro fermé. Quoi qu'il en soit, cela n'a pas à voir avec la cybersécurité, c'est juste pour tester les compétences logiques et de codage des étudiants.
Tâche
Écrivez un programme qui supprime les entrées d'un tableau afin que les valeurs restantes soient triées dans un ordre strictement décroissant et que leur somme soit maximisée parmi toutes les autres séquences décroissantes possibles.
Entrée et sortie
Entrée sera un tableau de valeurs entières strictement supérieur à 0
et tous différents les uns des autres . Vous êtes libre de choisir de lire l'entrée du fichier, de la ligne de commande ou de stdin.
La sortie sera un sous - tableau trié par ordre décroissant de celui d'entrée, dont la somme est supérieure à tout autre sous-tableau par ordre décroissant possible.
Note: [5, 4, 3, 2]
est un sous - tableau de [5, 4, 1, 3, 2]
, même si 4
et 3
ne sont pas adjacents. Tout simplement parce que le a 1
été sauté.
Solution Bruteforce
La solution la plus simple serait bien sûr d'itérer parmi toutes les combinaisons possibles du tableau donné et d'en rechercher un trié avec la plus grande somme, c'est-à-dire en Python :
import itertools
def best_sum_desc_subarray(ary):
best_sum_so_far = 0
best_subarray_so_far = []
for k in range(1, len(ary)):
for comb in itertools.combinations(ary, k):
if sum(comb) > best_sum_so_far and all(comb[j] > comb[j+1] for j in range(len(comb)-1)):
best_subarray_so_far = list(comb)
best_sum_so_far = sum(comb)
return best_subarray_so_far
Malheureusement, étant donné que la vérification du tri du tableau et le calcul de la somme de ses éléments le sont et que cette opération sera effectuée plusieurs fois pour de à , la complexité temporelle asymptotique sera
Défi
Votre objectif est d'obtenir une meilleure complexité temporelle que la bruteforce ci-dessus. La solution avec la plus petite complexité temporelle asymptotique est la gagnante du défi. Si deux solutions ont la même complexité temporelle asymptotique, le gagnant sera celui avec la plus petite complexité spatiale asymptotique.
Remarque: Vous pouvez envisager de lire, d'écrire et de comparer atomique même sur de grands nombres.
Remarque: S'il existe deux solutions ou plus, renvoyez l'une ou l'autre.
Cas de test
Input: [200, 100, 400]
Output: [400]
Input: [4, 3, 2, 1, 5]
Output: [4, 3, 2, 1]
Input: [50, 40, 30, 20, 10]
Output: [50, 40, 30, 20, 10]
Input: [389, 207, 155, 300, 299, 170, 158, 65]
Output: [389, 300, 299, 170, 158, 65]
Input: [19, 20, 2, 18, 13, 14, 8, 9, 4, 6, 16, 1, 15, 12, 3, 7, 17, 5, 10, 11]
Output: [20, 18, 16, 15, 12, 7, 5]
Input: [14, 12, 24, 21, 6, 10, 19, 1, 5, 8, 17, 7, 9, 15, 23, 20, 25, 11, 13, 4, 3, 22, 18, 2, 16]
Output: [24, 21, 19, 17, 15, 13, 4, 3, 2]
Input: [25, 15, 3, 6, 24, 30, 23, 7, 1, 10, 16, 29, 12, 13, 22, 8, 17, 14, 20, 11, 9, 18, 28, 21, 26, 27, 4, 2, 19, 5]
Output: [25, 24, 23, 22, 17, 14, 11, 9, 4, 2]
Réponses:
Perl
Cela devrait être O (n ^ 2) dans le temps et O (n) dans l'espace
Donnez des nombres séparés par un espace sur une ligne à STDIN
la source
Comment ça fonctionne
bestSubarrays xs
est la séquence de sous-réseaux dexs
qui se trouvent à la frontière efficace de {la plus grande somme, le plus petit premier élément}, ordonné de gauche à droite en augmentant la somme et en augmentant le premier élément.Pour aller de
bestSubarrays xs
àbestSubarrays (x:xs)
, nousx
, et un côté droit avec les premiers éléments supérieurs àx
,x
au le plus à droite sur le côté gauche,Un arbre de doigt prend en charge toutes ces opérations dansO ( logn ) temps.
la source
Cette réponse se développe sur celle de Ton Hospel.
Le problème peut être résolu avec la programmation dynamique en utilisant la récurrence
où( unje) est la séquence d'entrée et T( i ) la somme maximale réalisable de toute sous-séquence décroissante se terminant par un indice je . La solution réelle peut ensuite être retracée en utilisantT , comme dans le code de rouille suivant.
Essayez-le en ligne!
la source