Sie benötigen etwas Arbeitsspeicher dafür, wenn Sie für jedes Element in der verknüpften Liste keine Visited-Eigenschaft haben. Wenn Sie eine Visited-Eigenschaft haben, müssen Sie sie zuerst löschen, bevor Sie den Algorithmus ausführen. Dies wird wahrscheinlich nicht Ihren Big-O-Anforderungen entsprechen.
Es ist nicht klar, was Sie mit "Punkte bei vorherigen Listenelement" meinen. Ist gleich durch Referenz (Objekt) oder gleichen Wert/Menge von Eigenschaftswerten (struct)? Ich nehme Bezug auf. Der folgende Code kann leicht geändert werden, um auch Strukturen zu behandeln.
static void Main(string[] args)
{
var list = BuildALinkedListFromSomeData();
var isConsitent = IsConsistent(list);
}
static bool IsConsistent(LinkedList<Item> list)
{
var visited = new List<LinkedListNode<Item>>()
var runner = list.First;
while(runner != null)
{
if (visited.Contains(runner))
return false;
visited.Add(runner);
runner = runner.Next;
}
return true;
}
AO (n) Lösung, die einen vorhandenen numerischen VisitCounter verwendet, die bereits Speicherplatz verwendet (keine zusätzliche Speicherung erforderlich):
static bool IsConsistent(LinkedList<Item> list)
{
var runner = list.First;
if (runner == null)
return false; // Assume consistent if empty
var consistent = true;
var runId = runner.Value.VisitCount;
while (runner != null)
{
// Does the traversed item match the current run id?
if(runner.Value.VisitCount > runId)
{
// No, Flag list as inconsistent. It must have been visited previously during this run
consistent = false;
// Reset the visit count (so that list is ok for next run)
runner.Value.VisitCount = runId;
}
// Increase visit count
runner.Value.VisitCount++;
// Visit next item in list
runner = runner.Next;
}
return consistent;
}
Dies macht Änderungen an den Inhalt eines Elements in der Liste, aber nicht die Liste selbst. Wenn Sie den Inhalt eines Elements in der Liste nicht ändern dürfen, ist dies natürlich auch keine Lösung. Nun, ich denke, das ist keine mögliche Lösung. Wenn die Liste inkonsistent ist, ist sie kreisförmig und der letzte Algorithmus wird nie enden :)
Sie müssen dann die Liste rückwärts von jedem besuchten Element in Ihrer Liste durchlaufen und dies wird Ihre O (n + 1) Anforderung brechen.
Fazit: Nicht so Mission Impossible, wenn Count verfügbar ist. Siehe GrahamS 'Antwort
Kennen Sie 'n' im Voraus? – joop
nein, weil die Größe der Liste unbekannt ist. Also sollte der Algorithmus in der Lage sein, Konsistenz für jede Größe (oder n Elemente) zu überprüfen – Snelfie
Nun, in diesem Fall ist Floyds Algorithmus der beste, den Sie bekommen können (ohne zusätzlichen Speicher zu verwenden) – joop