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.

Author: almightyGOSU, 2015-07-21

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.

 2
Author: Chthonic Project, 2015-07-20 23:41:28