donnée n chaîne de longueur maximale m. Comment pouvons-nous trouver le préfixe commun le plus long partagé par au moins deux cordes parmi elles? P>
Exemple: ['Fleur', 'Flow', 'Hello', 'Fleet'] P>
Réponse: FL P>
Je pensais à construire une trie pour toute la chaîne, puis à vérifier le nœud le plus profond (satisfait le plus long) qui ramène à deux ou plus de sous-chaînes (satisfaire de points communs). Cela prend du temps et de l'espace O (n * m). Y a-t-il une meilleure façon de faire cela p>
8 Réponses :
Je les trierais, que vous pouvez faire dans n lg n code> temps. Ensuite, toutes les cordes avec des préfixes courants seront juste à côté de l'autre. En fait, vous devriez pouvoir conserver un pointeur de quel index vous examinez actuellement et travaillez votre chemin pour un court calcul rapide. P>
Le tri prendrait NMLOG (NM) car la comparaison dans le pire des cas prend o (m)
en fait, il le fait O (m * nlog (n)) code> et non o (nmlog (nm)) code>, car comme vous avez dit: la comparaison prend o (m ) code>, et il y a O (nlogn) code> de ceux-ci, ce qui aboutit au total O (mnlog (n)) code>
Dans le pire des cas, oui c'est vrai. Cependant, ce pire des cas ne s'applique que lorsque les cordes elles-mêmes sont très, très similaires, ce qui signifie qu'il y aurait beaucoup moins d'échange. Je n'ai pas fait les mathématiques dessus, et il est concevable qu'un cas contraignait le causerait de se dégrader, mais cela semble toujours comme la meilleure option, en particulier compte tenu de l'espace.
De plus, la notion de m code> est uniquement importante lorsque m code> est significativement proche de ou supérieur à n code>. Un M CODE> sera de 12 ou moins pour les mots anglais standard, et si nous envisageons des mots non inventés, non techniques, nous examinons 33 (antidiistablicimératoire). Donc, il a un impact si votre N code> est, disons, 100 ou moins, mais si tel est le cas, toute votre opération est petite et O code> ne s'applique pas. O code> La notation est pour l'évaluation asymptotique.
Il y a un O (| s | * n) code> solution à ce problème, à l'aide d'un Trie . [ n code> est le nombre de chaînes, s code> est la chaîne la plus longue]
C'est la méthode que je pensais aussi et décrit dans le problème. Je suis d'accord avec la limite inférieure du temps car nous devons lire chaque chaîne une fois. La complexité spatiale est toujours O (n * m), pouvons-nous faire mieux?
@shreyasva: Actualisez votre page, j'ai ajouté une phrase expliquant pourquoi ce problème est oméga (n * m) code>, donc aucune solution ne peut faire mieux que o (n * m) code>
Je n'ai pas compris la solution DFS. Pouvez-vous donner un exemple?
Ne pouvons-nous pas simplement aller de gauche à droite vérifier si le caractère à la position X est identique pour toutes les chaînes, supprimez la chaîne pour laquelle cela n'est pas rencontré et itérale comme ça jusqu'à ce que nous allions à la fin de la chaîne la plus courte ou nous avoir seulement 1 chaîne dans notre éventail de chaînes. Nous devons juste vous rappeler le dernier préfixe le plus long. La même complexité de la fois mais pas besoin d'une trie.
comme une réponse complètement différente de mon autre réponse ... p>
Vous pouvez, avec une passe, godet chaque chaîne basée sur sa première lettre. P>
Avec une autre passe, vous pouvez trier chaque godet en fonction de sa seconde plus tard. (Ceci est connu sous le nom de triadix, qui est Vous pouvez supprimer en toute sécurité de votre ensemble de données tout élément qui n'a pas de préfixe de 2. P>
Vous pouvez continuer le tri radix, supprimer des éléments sans préfixe partagée de Cela vous donnera le même Le pire des cas est toujours que chaque chaîne est identique, c'est pourquoi elle partage la même notation Big O, mais sera plus rapide dans tous les cas, car il est garanti d'utiliser moins de comparaisons depuis n'importe quel "non-pire cas" sont des personnages qui n'ont jamais besoin d'être visités. p> O (n * m) code> et O (n) code> avec chaque passage.) Cela vous donne un préfixe de base de 2. p>
p code>, comme p code> approche m code>. p>.
O (n * m) CODE> TIME que l'approche Trie, mais sera toujours plus rapide que la trie puisque la trie doit regarder tous les personnages de chaque chaîne (comme Il entre dans la structure), tandis que cette approche n'est garantie que 2 caractères par chaîne, à laquelle cela frappe une grande partie de l'ensemble de données. P>
Pourquoi utiliser Trie (qui prend l'espace O (MN) Time and O (mn), utilisez simplement la force de force brute de base. Première boucle, trouvez la chaîne la plus courte en tant que MINSTR, qui prend O (n) temps, deuxième boucle , Comparez-en une à une avec ce Mintr, et conservez une variable qui indique l'indice le plus à droite de Mintr, cette boucle prend o (mn) où M est la longueur la plus courte de toutes les chaînes. Le code est comme ci-dessous,
public String longestCommonPrefix(String[] strs) {
if(strs.length==0) return "";
String minStr=strs[0];
for(int i=1;i<strs.length;i++){
if(strs[i].length()<minStr.length())
minStr=strs[i];
}
int end=minStr.length();
for(int i=0;i<strs.length;i++){
int j;
for( j=0;j<end;j++){
if(minStr.charAt(j)!=strs[i].charAt(j))
break;
}
if(j<end)
end=j;
}
return minStr.substring(0,end);
}
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0)
return "";
char[] c_list = strs[0].toCharArray();
int len = c_list.length;
int j = 0;
for (int i = 1; i < strs.length; i++) {
for (j = 0; j < len && j < strs[i].length(); j++)
if (c_list[j] != strs[i].charAt(j))
break;
len = j;
}
return new String(c_list).substring(0, len);
}
Solution géniale;)
Il arrive que le type de seau (Tri radix) décrit par Corsika puisse être étendu de manière à ce que toutes les cordes soient finalement placées seules dans un seau et à ce stade, le LCP pour une chaîne aussi solitaire est connue. En outre, l'intrigant de chaque chaîne est également connue; C'est un plus long que le LCP. Le type de godet est défacto la construction d'un ensemble de suffixe, mais seulement partiellement. Ces comparaisons qui ne sont pas effectuées (comme décrit par CORIKA) représentent en effet ces parties des chaînes suffixes qui ne sont pas ajoutées à la matrice suffixe. Enfin, cette méthode permet de déterminer non seulement le LCP et les diffuseurs, mais également on peut facilement trouver ces sous-séquences qui ne sont pas présentes dans la chaîne. P>
Puisque le monde mendie évidemment pour une réponse à Swift, voici la mienne;) Qu'est-ce qui est intéressant à noter: p> et donné la fonction que je devais écrire en premier lieu: p> Voici un test d'unité minimal: P>
le type code> représente. li>
ol> func testReifySimple() {
let samplePaths:[String] = [
"/root/some/file"
, "/root/some/other/file"
, "/root/another/file"
, "/root/direct.file"
]
let expectedPaths:[String] = [
"some/file"
, "some/other/file"
, "another/file"
, "direct.file"
]
let reified = PathUtilities().reify(samplePaths)
for (index, expected) in expectedPaths.enumerate(){
XCTAssert(expected == reified[index], "failed match, \(expected) != \(reified[index])")
}
}
Peut-être une solution plus intuitive. Channel le préfixe déjà trouvé hors de l'itération antérieure en tant que chaîne d'entrée sur l'entrée de chaîne restante ou suivante. [[[[W1, W2], W3], W4] ... Donc] Code>, où [] code> est supposément le LCP de deux cordes. public String findPrefixBetweenTwo(String A, String B){
String ans = "";
for (int i = 0, j = 0; i < A.length() && j < B.length(); i++, j++){
if (A.charAt(i) != B.charAt(j)){
return i > 0 ? A.substring(0, i) : "";
}
}
// Either of the string is prefix of another one OR they are same.
return (A.length() > B.length()) ? B.substring(0, B.length()) : A.substring(0, A.length());
}
public String longestCommonPrefix(ArrayList<String> A) {
if (A.size() == 1) return A.get(0);
String prefix = A.get(0);
for (int i = 1; i < A.size(); i++){
prefix = findPrefixBetweenTwo(prefix, A.get(i)); // chain the earlier prefix
}
return prefix;
}
@Mark je crois que cet exemple serait
flux code>. À en juger par le contexte de la solution proposée, il doit être commun à au moins 2, contre tous. Je conviens que certaines éclaircissements de l'OP sont nécessaires ici.Une chaîne peut commencer sans 'fl'. 'Bonjour' a été mis à prouver un point qu'il pourrait être des chaînes où dans une chaîne ne doit pas avoir de préfixe commun avec les autres