Craquage de la liste Chaînée Circulaire d'Entrevue de codage
La question: Étant donné une liste chaînée circulaire, implémentez un algorithme qui renvoie le nœud au début de la boucle.
Définition: Liste chaînée circulaire: Une liste chaînée (corrompue) dans laquelle le pointeur suivant d'un nœud pointe vers un nœud antérieur, de manière à faire une boucle dans la liste chaînée.
Exemple: Entrée: A - > B - > C - > D - > E - > C[le même C que précédemment] Sortie: C
Ma solution est de garder une trace des nœuds vus dans une ArrayList, puis une fois que j'arrive à un le nœud que j'ai déjà vu, alors je sais que c'est le nœud au début de la boucle.
Fonction FindBeginningLoop:
public Node findBeginningLoop(Node n) {
ArrayList<Node> nodes = new ArrayList<Node>();
Node pointer = n;
while (true) {
Node checkingNode = pointer;
if (!nodes.contains(checkingNode)) {
nodes.add(checkingNode);
} else {
return checkingNode;
}
}
}
Classe de nœud:
public class Node {
Node next = null;
int val;
public Node(int d) {
val = d;
}
public void appendToTail(int d) {
Node end = new Node(d);
Node n = this;
while (n.next != null) {
n = n.next;
}
n.next = end;
}
}
Sa solution est d'utiliser un pointeur rapide et un pointeur lent. Cette solution est-elle bien meilleure?
Merci.
1 answers
En termes de complexité spatiale, oui sa solution est évidemment meilleure. Votre solution vous oblige à maintenir tous les nœuds qui ont déjà été vus, ce qui est O(n)
, n
étant la taille de la liste.