La programmation dynamique: Trouver la plus longue sous-suite qui est en zig zag
Quelqu'un peut s'il vous plaît aidez-moi à comprendre la logique de base derrière la solution à un problème mentionné à http://www.topcoder.com/stat?c=problem_statement&pm=1259&rd=4493
Zig zag séquence est une alternativement des augmentations et des diminutions. Donc, 1 3 2 est en zig zag, mais 1 2 3 ne l'est pas. Toute séquence d'un ou de deux éléments de zig zag. Nous avons besoin de trouver le plus long zig-zag en sous-suite dans une séquence donnée. Sous-suite signifie qu'il n'est pas nécessaire pour les éléments à contigus, comme dans la plus longue sous-suite croissante problème. Donc, 1 3 5 4 2 pourrait avoir 1 5 4 zig zag sous-suite. Nous nous sommes intéressés à la plus longue.
Je comprends que c'est un problème de programmation dynamique et il est très similaire à Comment faire pour déterminer la plus longue sous-suite croissante utilisant la programmation dynamique?.
Je pense que toute solution aurez besoin d'une boucle externe qui effectue une itération sur des séquences de longueurs différentes, et la boucle interne aura pour itérer sur toutes les séquences.
Nous allons stocker la plus longue zig zag séquence se terminant à l'indice i dans un autre tableau, dire dpStore à l'indice i. Ainsi, les résultats intermédiaires sont stockées, et peuvent ensuite être réutilisés. Cette partie est commune à tous les problèmes de programmation Dynamique. Plus tard, nous avons trouver le maximum global et le retourner.
Ma solution est certainement mauvais, coller ici pour montrer ce que j'ai jusqu'à présent. Je veux savoir où je suis allé mal.
private int isZigzag(int[] arr)
{
int max=0;
int maxLength=-100;
int[] dpStore = new int[arr.length];
dpStore[0]=1;
if(arr.length==1)
{
return 1;
}
else if(arr.length==2)
{
return 2;
}
else
{
for(int i=3; i<arr.length;i++)
{
maxLength=-100;
for(int j=1;j<i && j+1<=arr.length; j++)
{
if(( arr[j]>arr[j-1] && arr[j]>arr[j+1])
||(arr[j]<arr[j-1] && arr[j]<arr[j+1]))
{
maxLength = Math.max(dpStore[j]+1, maxLength);
}
}
dpStore[i]=maxLength;
}
}
max=-1000;
for(int i=0;i<arr.length;i++)
{
max=Math.max(dpStore[i],max);
}
return max;
}
Je suis désolé, je n'avais pas remarqué que... je vais mettre dans un rapide exposé du problème.
Voulez-vous comprendre comment faire pour résoudre à la base de la plus longue sous-suite croissante (sans le zigzag)? C'est juste une modification mineure, en utilisant les mêmes techniques à résoudre.
Dans
1 3 5 4 2
, la séquence entière est zig-zag
. Vous n'avez pas parler de la façon dont l'égalité des numéros doivent être traités, mais à l'exclusion de l'égalité des nombres, ne sont pas toutes les séquences qui ne sont pas en augmentant ou en diminuant (ils n'ont pas de zigzag de sous-séquences, à l'exception de ce qui est insignifiant 1 ou 2 éléments). Alors, est - 1 1 1
croissante ou décroissante?Eh bien, le problème est lié à ce qui est complètement différent de ce que vous décrivez. Pouvez vous s'il vous plaît décider sur lequel vous avez besoin d'aide?
OriginalL'auteur Abhijeet Kashnia | 2011-08-02
Vous devez vous connecter pour publier un commentaire.
C'est ce que le problème est lié à dit:
C'est complètement différent de ce que vous avez décrit dans votre post. Le suivant résout le réel topcoder problème.
Exemple:
Puis il suffit de prendre le max de deux
dp
tableaux.dp
ici? Est-il une matrice de 2 lignes et n colonnes?dp[i][1] correspondant à des valeurs de 13 et 15 3 au lieu de 2 selon la définition.
Salut @IVlad, après le calcul que 7 est la longueur maximum de la sous-matrice, comment avez-vous obtenir l'7 éléments?
Il y a aussi un linéaire de la solution à ce problème, voir la réponse ci-dessous.
pouvez-vous s'il vous plaît écrire une relation récursive pour cet algorithme
OriginalL'auteur IVlad
C'est une solution plus simple
Laisser le tableau original, Un être de longueur n. La construction de la matrice B de taille n-1, seulement des 0 et des 1. B[i] = 0 si a[i]-[i+1] >=0 sinon B[i] = 1. Cela peut être fait en O(n). Maintenant, nous avons un tableau de seulement des 0 et des 1, le problème est maintenant de trouver une alternance continue des 0 et des 1. En continu d'une sous-matrice de matrice dans B de 0 sera représenté par l'une quelconque de ses éléments. Par exemple:
Si B = [0,0,0,0,0, 1,0,0,0,1,0,1,1,1,0] ensuite, nous pouvons réduire le B du Br qui = [0,1,0,1,0,1,0] en O(n), en fait nous avons juste besoin de trouver la taille de Br qui peut être fait par une seule itération. Et que mon ami est la réponse à un problème donné. Donc total de la complexité est O(n) + O(n) = O(n).
En d'autres termes:
Garder le premier élément. Ensuite, trouver le ton monotone croissante ou la diminution de certaines parties de la séquence et de garder le dernier élément de l'ensemble de ces séquences.
Mise à JOUR: Vous devez en ajouter un à la réponse de sortir de ce processus, parce que vous êtes en comptant les zigzags, et non pas la longueur de la liste. Méfiez-vous de poteau de la clôture problème: https://betterexplained.com/articles/learning-how-to-count-avoiding-the-fencepost-problem/
pouvez-vous prouver l'optimalité de cet algorithme?
Olayinka: Vous ne pouvez pas avoir un algorithme qui est mieux que O(n) si il y a qu'à lire chaque élément de longueur n de tableau.
votre solution n'a pas de travail pour
1 17 5 10 13 15 10 5 16 8
icib
devenir[1 0 1 1 1 0 0 1 0]
etbr
deviendra[1 0 1 0 1 0]
de sorte que votre algo donner6
mais la réponse est7
cette solution ne fonctionne pas
OriginalL'auteur surya
Il y a une approche gourmande aussi.
Prendre le premier élément. Puis de trouver le minimum ou le maximum de l'élément dans la séquence contiguë, y compris le premier élément et sélectionnez-la.
Qui est si la séquence est
1, 5, 7, 9, 2,4
, sélectionnez d'abord 1, puis 9 car 9 est le maximum dans la séquence contiguë1, 5, 7, 9
.Procéder de la même manière et sélectionnez 2 et 5.
En utilisant la même approche, la sous-suite calculé pour l'exemple:
est:
1, 17, 5, 15, 5, 16, 8
cette approche gourmande de réduire la complexité à O(n) >
Ne fonctionne pas.
1, 2, 1, 2, 9, 1
OriginalL'auteur user434345
ou vous pouvez utiliser l'algorithme glouton
OriginalL'auteur Aydar Omurbekov
En fait, je pense que répondre avec le plus haut score est correct (IVlad). Mais je suis assez sûr que la dynamique de la partie programmation (boucle externe) est pas nécessaire.
Une approche gourmande est utilisé et on peut obtenir
positive_end_seq[i]
etnegative_end_seq[i]
par des opérations:positive_end_seq[0] = 1
etnegative_end_seq[0] = 1
, les deux tableaux pour tous lesi
s'contient la longueur de la plus longue sous-suite avec pos/nég se terminant eni
-ième élément. Nous n'avons pas à regarder0..i-2
éléments, et il serait bien de prouver que.Complexité temporelle est
O(n)
Bien sûr, pos/neg tableau peuvent être remplacés par des compteurs maintenant, voici le code en Java
OriginalL'auteur The_Ham
OriginalL'auteur vishpat
C'est mon point de vue sur un simple avide de mise en œuvre.
Comme d'autres l'ont déjà mentionné, il vous suffit de regarder les zag avec les trois derniers points.
OriginalL'auteur Thomas Ahle
Ici est de savoir comment il l'a fait en O(n)
OriginalL'auteur Sandip
int zigzag(int[] a) {
}
OriginalL'auteur jchopra
def ZigZag(tup):
OriginalL'auteur lucifer
De sélection locale de maxima et de minima locaux, très simple.
OriginalL'auteur Lukas Mach