J'ai récemment interviewé une entreprise et ils m'ont demandé d'écrire un algorithme qui trouve la sous-séquence avec la plus grande somme d'éléments dans un tableau. Les éléments du tableau peuvent être négatifs. Y a-t-il une solution O (n) pour cela? Toutes les bonnes solutions sont très appréciées.Trouver la sous-séquence avec la plus grande somme d'éléments dans un tableau
Répondre
Si vous voulez la plus grande somme de numéros séquentiels alors quelque chose comme cela pourrait fonctionner:
$cur = $max = 0;
foreach ($seq as $n)
{
$cur += $n;
if ($cur < 0) $cur = 0;
if ($cur > $max) $max = $cur;
}
C'est juste à côté du haut de ma tête, mais il semble juste. (Ignorant qu'il suppose 0 est la réponse pour vide et tous les jeux négatifs.)
Edit:
Si vous voulez aussi la position de séquence:
$cur = $max = 0;
$cur_i = $max_i = 0;
$max_j = 1;
foreach ($seq as $i => $n)
{
$cur += $n;
if ($cur > $max)
{
$max = $cur;
if ($cur_i != $max_i)
{
$max_i = $cur_i;
$max_j = $max_i + 1;
}
else
{
$max_j = $i + 1;
}
}
if ($cur < 0)
{
$cur = 0;
$cur_i = $i + 1;
}
}
var_dump(array_slice($seq, $max_i, $max_j - $max_i), $max);
Il pourrait y avoir une façon plus concise fais le. Encore une fois, il a les mêmes hypothèses (au moins un entier positif). En outre, il ne trouve que la première plus grande séquence. Editer: modifié pour utiliser max_j
(exclusif) au lieu de max_len
.
Ce n'est pas ce qu'il cherche. Il a demandé une sous-séquence qui a la somme maximale. Vous lui avez donné la sous-séquence contiguë avec max. somme. Dans la sous-séquence, les nombres ne sont pas nécessairement contigus. –
@Kapil D, ma réponse commence très clairement en disant ce qu'il répond. Était-ce ce que recherchaient ses intervieweurs? Nous ne le saurons jamais. C'est évidemment ce qu'il cherchait, comme il l'a accepté. (S'il voulait vraiment une sous-séquence avec la plus grande somme, la réponse est triviale: supprimer tous les nombres négatifs.) – Matthew
Oui, je sais que vous l'avez écrit pour un numéro séquentiel. Peut être la personne qui a écrit la question n'était pas claire. J'aime ta solution au problème de la séquence max. –
Je suppose que vous voulez dire plus longue sous-séquence croissante. Il n'existe pas de solution O(n)
pour cela.
Une solution très naïve serait de créer un tableau dupliqué, le trier en O(NlogN)
et ensuite trouver le LCS
du tableau trié et tableau original qui prend O(N^2)
.
Il existe également une solution directe basée sur DP similaire à LCS
qui prend également O(N^2)
, que vous pouvez voir here.
Mais si vous voulez dire la plus longue séquence croissante (consécutive). Cela peut être fait en O(N)
.
Si vous voulez dire plus longue sous-séquence croissante, voir codaddict réponse.
Si d'autre part vous voulez dire trouver le tableau sous avec la somme maximale (n'a de sens que des valeurs négatives), alors il y a un style de programmation élégante, dynamique solution de temps linéaire:
Bon lien. Il semble que ma réponse était juste une implémentation de cet algorithme. – Matthew
@konforce: exactement. Vous devez également enregistrer les positions de début et de fin pour renvoyer le sous-réseau lui-même, bien sûr. +1 –
+1 ... Trouver cet algorithme est un exercice de routine dans la plupart des cours CS intro (CS 101 ou CS 102). –
fonction C ressemble à ceci:
int largest(int arr[], int length)
{
int sum= arr[0];
int tempsum=0;
for(int i=0;i<length;i++){
tempsum+=arr[i];
if(tempsum>sum)
sum=tempsum;
if(tempsum<0)
tempsum=0;
}
return sum;
}
Essayez le code suivant:
#include <stdio.h>
int main(void) {
int arr[] = {-11,-2,3,-1,2,-9,-4,-5,-2, -3};
int cur = arr[0] >= 0? arr[0] : 0, max = arr[0];
int start = 0, end = 0;
int i,j = cur == 0 ? 1 : 0;
printf("Cur\tMax\tStart\tEnd\n");
printf("%d\t%d\t%d\t%d\n",cur,max,start,end);
for (i = 1; i < 10; i++) {
cur += arr[i];
if (cur > max) {
max = cur;
end = i;
if (j > start) start = j;
}
if (cur < 0) {
cur = 0;
j = i+1;
}
printf("%d\t%d\t%d\t%d\n",cur,max,start,end);
}
getchar();
}
void longsub(int a[], int len) {
int localsum = INT_MIN;
int globalsum = INT_MIN;
int startindex = 0,i=0;
int stopindex = 0;
int localstart = 0;
for (i=0; i < len; i++) {
if (localsum + a[i] < a[i]) {
localsum = a[i];
localstart = i;
}
else {
localsum += a[i];
}
if (localsum > globalsum) {
startindex = localstart;
globalsum = localsum;
stopindex = i;
}
}
printf ("The begin and end indices are %d -> %d (%d).\n",startindex, stopindex, globalsum);
}
Ce problème peut être résolu de deux manières différentes.
La première approche a deux variables appelées sum
et MaxSum
.
Nous allons continuer à ajouter des valeurs à la somme et comparerons avec le maxsum, si la valeur de la somme est supérieure à la maxsum - va attribuer une valeur de somme au maxsum
Si au cours de la traiter la valeur pour que la somme passe en dessous de 0, nous allons réinitialiser la somme et commencerons à ajouter un nouveau numéro à partir de l'index suivant. L'exemple de code pour la solution ci-dessus est fourni ci-dessous:
private static void FindMaxSum(int[] array) { int sum = 0; int MaxSum = 0; for (int i = 0; i < array.Length; i++) { sum += array[i]; if (sum > MaxSum) { MaxSum = sum; } else if (sum < 0) { sum = 0; } } Console.WriteLine("Maximum sum is: " + MaxSum); }
La seconde approche pour résoudre ce problème est que nous allons passer par chaque élément dans un tableau. Nous aurons les mêmes 2 variables de somme et MaxSum.
Nous allons d'abord comparer l'addition de sum avec l'élément de tableau suivant et la somme elle-même. Qui est le plus grand - cette valeur sera stockée dans la variable somme.
Ensuite, nous allons comparer les valeurs de sum et MaxSum et celui qui a la plus grande valeur - nous allons enregistrer cette valeur dans la variable MaxSum. L'exemple de code est tel que mentionné ci-dessous:
private static void FindMaxSum(int[] array) { int sum = array[0], Maxsum = array[0]; for (int i = 1; i < array.Length; i++) { sum = Max(sum + array[i], array[i]); Maxsum = Max(sum, Maxsum); } Console.WriteLine("Maximum sum is: " + Maxsum); } private static int Max(int a, int b) { return a > b ? a : b; }
Si vous demandez ce qui est une sous contiguës dont la somme est maximale, j'ai trouvé 4 algos jusqu'à présent: -
Brute-force: Trouvez toutes les sommes possibles en utilisant des boucles imbriquées et continuez à mettre à jour le maxSum si vous trouvez une somme supérieure à la valeur précédente de maxSum. La complexité est en O (n^2)
Programmation dynamique Solution: Ceci est une solution remarquablement élégante que je trouve sur StackOverflow lui-même - https://stackoverflow.com/a/8649869/2461567v - complexité Temps: O (n), complexité de l'espace: O (n)
DP sans mémoire - Kadane algorithme - https://en.wikipedia.org/wiki/Maximum_subarray_problem - complexité Temps: O (n), la complexité de l'espace: O (1)
Divide and Conquer Solution - http://eecs.wsu.edu/~nroy/courses/CptS223/notes/MaxSubsequenceSum.pdf complexité Temps: O (NLGN)
- 1. Trouver la plus grande valeur du sous-ensemble du tableau
- 2. Trouver la longueur de la plus grande séquence croissante
- 3. Trouver et marquer la plus grande des trois valeurs dans un tableau à deux dimensions
- 4. Trouver la plus grande valeur inférieure à x dans un tableau trié
- 5. Trouver les éléments d'un tableau basé sur la somme minimale
- 6. Trouver la chaîne la plus commune dans un tableau
- 7. Imprime la ligne avec la plus grande longueur, la ligne avec la plus haute somme de valeurs ASCII, ou la ligne avec le plus grand nombre de mots
- 8. Trouver la plus longue séquence dans un tableau Java
- 9. Comment trouver la deuxième plus grande valeur d'une table.?
- 10. Somme dans le tableau avec la valeur de correspondance
- 11. Code ParallelFor pour trouver la somme de quelques éléments dans un tableau (problème SubsetSum)
- 12. trouver la correspondance la plus proche du tableau de doubles
- 13. Trouver la chaîne la plus longue dans plusieurs textes
- 14. Comment obtenir une taille de tableau (et la plus grande) avec une instruction SQL?
- 15. Trouver la somme de selected in flot
- 16. Trouver Somme dans LINQ
- 17. Méthode la plus rapide pour calculer la somme de bits dans le tableau d'octets
- 18. MySQL comptant la plus grande valeur
- 19. Trouver la somme de toutes les valeurs des filateurs avec la même classe
- 20. Trouver un enregistrement dans la table mysql qui a la valeur la plus élevée
- 21. Linq pour trouver une paire de points avec la plus grande longueur?
- 22. requête pour obtenir 3ème plus grande quantité et 2ème plus grande quantité de la table
- 23. Trouver la valeur la plus élevée dans un Enumeration
- 24. requête pour trouver la première et la plus grande valeur SECOND d'un groupe
- 25. Trouver la plus proche
- 26. tableau php somme récursive
- 27. Numéros de somme dans un tableau
- 28. Trouver une sous-matrice avec la somme maximale possible dans O (n^2)
- 29. Trouver la plus haute clé
- 30. La plus grande colonne non nulle
vouliez-vous dire ** longest ** subsequence? Aussi est-il le plus long à augmenter? – codaddict
Que voulez-vous dire par "plus grande subséquance"? -- Ah d'accord. Vous voulez probablement dire: trouvez la sous-séquence avec la plus grande somme d'éléments. – sellibitze
voulez-vous dire la plus longue séquence de nombre telle que la somme de ces nombres est la plus grande dans un tableau? – jsshah