[Code Caprice | Leetcode | Tag 7] Verlinkte Liste | Linked List Intersection | Ring Linked List II

Vorwort

Willkommen in der Leetcode|Code Caprice|Thematischen Kolumne von Little K. Heute werde ich Ihnen das Teilen von Linked-List-Schnittpunkten und zirkulären Linked-List- II✨ vorstellen


Interviewfrage 02.07. Linked List Intersection

✨Den Themenlink klicken Sie hier

Suchen Sie anhand der Kopfknoten headA und headB zweier einfach verknüpfter Listen den Startknoten, an dem sich die beiden einfach verknüpften Listen schneiden, und geben Sie ihn zurück. Gibt null zurück, wenn sich die beiden verknüpften Listen nicht überschneiden.

Zeigen Sie, dass sich zwei verknüpfte Listen beginnend beim Knoten c1 schneiden:

Fügen Sie hier eine Bildbeschreibung ein

Die Titeldaten garantieren, dass es in der gesamten Kettenstruktur keine Schleifen gibt.
Beachten Sie, dass die verknüpfte Liste ihre ursprüngliche Struktur beibehalten muss, nachdem die Funktion das Ergebnis zurückgibt.

Beispiel 1:

Eingabe : intersectVal = 8, ListeA = [4,1,8,4,5], ListeB = [5,0,1,8,4,5], SkipA = 2, SkipB = 3 Ausgabe
: Schnittpunkt bei „8“
Erläuterung : Der Wert des Schnittknotens ist 8 (beachten Sie, dass er nicht 0 sein kann, wenn sich zwei verknüpfte Listen schneiden).
Von den jeweiligen Headern aus gezählt, ist die verknüpfte Liste A [4,1,8,4,5] und die verknüpfte Liste B ist [5,0,1,8,4,5].
In A gibt es 2 Knoten vor dem Schnittpunkt; in B gibt es 3 Knoten vor dem Schnittpunkt.

Beispiel 2:

Eingabe : intersectVal = 2, ListeA = [0,9,1,2,4], ListeB = [3,2,4], SkipA = 3, SkipB = 1 Ausgabe
: Schnittpunkt bei „2“
Erläuterung : Der Wert des Schnittknotens ist 2 (beachten Sie, dass er nicht 0 sein kann, wenn sich die beiden verknüpften Listen schneiden).
Von den jeweiligen Headern aus gezählt, ist die verknüpfte Liste A [0,9,1,2,4] und die verknüpfte Liste B ist [3,2,4].
In A gibt es 3 Knoten vor dem Schnittpunkt; in B gibt es 1 Knoten vor dem Schnittpunkt.

Beispiel 3:

Eingabe : intersectVal = 0, ListeA = [2,6,4], ListeB = [1,5], SkipA = 3, SkipB = 2 Ausgabe
: null
Erläuterung : Von den jeweiligen Headern aus gezählt, ist die verknüpfte Liste A [2,6,4] und die verknüpfte Liste B ist [1,5].
Da die beiden verknüpften Listen disjunkt sind, muss „intersectVal“ 0 sein, während „skipA“ und „skipB“ beliebige Werte sein können.
Die beiden verknüpften Listen sind disjunkt, daher wird null zurückgegeben.

Hinweis:

Die Anzahl der Knoten in ListeA ist m.
Die Anzahl der Knoten in ListeB ist n

0 <= < = m, n3 * 104
1 <= < Node.val= 105
0 <= < skipA= m
0 <= skipB<= nWenn es keinen Schnittpunkt mit gibt und 0
Wenn es einen Schnittpunkt gibt, ist die Idee: Diese Frage ist auch eine Verwendung von Doppelzeigern. Wir definieren zuerst zwei Zeiger, die auf die Kopfknoten der beiden verknüpften Listen zeigen, und lassen dann den Zeiger, der auf die längere verknüpfte Liste zeigt, sich bewegen rückwärts, am Zeiger der kürzeren verknüpften Liste ausrichten und schließlich einen sich bewegenden, zyklischen Vergleich durchführen, die ersten beiden Zeiger zurückgeben, die auf denselben Knoten zeigen, und leer zurückgeben, wenn sie nicht gefunden werdenlistA listBintersectVal
listAlistBintersectVal == listA[skipA + 1] == listB[skipB + 1]

class Solution {
    
    
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
        ListNode* curA = headA, *curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != nullptr) {
    
    
            lenA++;
            curA = curA->next;
        }
        while (curB != nullptr) {
    
    
            lenB++;
            curB = curB->next;
        }
        curA = headA;
        curB = headB;
        if (lenA < lenB){
    
    
            swap(lenA,lenB);
            swap(curA,curB);
        }
        int gap = lenA - lenB;
        while (gap--) curA = curA->next;
        while (curA != nullptr) {
    
    
            if(curA == curB) return curA;
            curA = curA->next;
            curB = curB->next;
        }
        return nullptr;
    }
};

Fügen Sie hier eine Bildbeschreibung ein

142. Zirkuläre verlinkte Liste II

✨Titelverknüpfung hier:
Geben Sie bei gegebenem Kopfknoten head einer verknüpften Liste den ersten Knoten der verknüpften Liste zurück, der beginnt, in den Ring einzutreten. Gibt null zurück, wenn die verknüpfte Liste azyklisch ist. Wenn es in der verknüpften Liste einen Knoten gibt, der durch kontinuierliches Verfolgen des nächsten Zeigers wieder erreicht werden kann, dann liegt in der verknüpften Liste ein Zyklus vor. Um den Ring in der angegebenen verknüpften Liste darzustellen, verwendet das Bewertungssystem intern die Ganzzahl pos, um die Position anzugeben, an der das Ende der verknüpften Liste mit der verknüpften Liste verbunden ist (der Index beginnt bei 0). Wenn pos -1 ist, enthält die Liste keine Zyklen. Hinweis: pos wird nicht als Parameter übergeben, sondern dient lediglich der Identifizierung der tatsächlichen Situation der verknüpften Liste.
Die verknüpfte Liste darf nicht geändert werden.

Beispiel 1:
Fügen Sie hier eine Bildbeschreibung ein

Eingabe : Kopf = [3,2,0,-4], Pos = 1
Ausgabe : Geben Sie den Knoten der verknüpften Liste mit Index 1 zurück.
Erläuterung : In der verknüpften Liste gibt es einen Ring, dessen Ende mit dem zweiten Knoten verbunden ist.

Beispiel 2:
Fügen Sie hier eine Bildbeschreibung ein

Eingabe : Kopf = [1,2], Pos = 0
Ausgabe : Geben Sie den Knoten der verknüpften Liste mit Index 0 zurück .
Erläuterung : In der verknüpften Liste gibt es einen Ring, dessen Ende mit dem ersten Knoten verbunden ist.

Beispiel 3:
Fügen Sie hier eine Bildbeschreibung ein

Eingabe : head = [1], pos = -1
Ausgabe : null zurückgeben
Erläuterung : Die verknüpfte Liste enthält keinen Ring.

Hinweis:
Die Anzahl der Knoten in der verknüpften Liste liegt im Bereich [0, 104]
-105 <= Node.val<= 105.
Der Wert von pos ist -1 oder ein gültiger Index in der verknüpften Liste

Idee: Um dieses Problem zu lösen, müssen wir die folgenden zwei Probleme klären

  • Bestimmen Sie, ob eine verknüpfte Liste einen Zyklus hat
  • Wenn es einen Ring gibt, wie findet man den Eingang zu diesem Ring?

Frage 1: Bestimmen Sie, ob die verknüpfte Liste einen Ring hat

Sie können die schnelle und langsame Zeigermethode verwenden, um einen schnellen Zeiger und einen langsamen Zeiger langsam zu definieren. Beginnen Sie mit dem Kopfknoten und lassen Sie den schnellen Zeiger jedes Mal zwei Knoten und den langsamen Zeiger jedes Mal einen Knoten bewegen. Wenn sie sich auf dem Weg treffen, bedeutet dies, dass es einen Zyklus gibt

Begegnungen müssen innerhalb des Rings stattfinden, warum ist das so? Der schnelle Zeiger muss vor dem langsamen Zeiger in den Ring gelangen.
Warum treffen sich der schnelle und der langsame Zeiger immer? Der schnelle Zeiger bewegt sich jeweils um zwei Schritte und der langsame Zeiger um jeweils einen Schritt. Der schnelle Zeiger entspricht also dem Schritt für Schritt, den langsamen Zeiger einzuholen, sodass sie sich definitiv treffen

Fügen Sie hier eine Bildbeschreibung ein

Frage 2: Finden Sie den Eingang des Rings

Angenommen, die Anzahl der Knoten vom Kopfknoten bis zum Ringeintrittsknoten beträgt x. Die Anzahl der Knoten vom Ringeintrittsknoten bis zum Knoten, an dem der schnelle Zeiger auf den langsamen Zeiger trifft, beträgt y. Die Anzahl der Knoten vom Begegnungsknoten bis zum Ringeintrittsknoten beträgt z.
Wenn sie sich dann treffen: Die Anzahl der Knoten, die der langsame Zeiger passiert hat, ist: , x + ydie Anzahl der Knoten, die der schnelle Zeiger passiert hat: , n ist derx + y + n (y + z) schnelle Zeiger, der n Kreise im Ring durchlaufen hat, bevor er auf den langsamen Zeiger gestoßen ist, und ist die Anzahl der (y+z)Knoten in einem Kreis. niedriger Zeiger.

Wenn n gleich eins und größer als eins ist, ist der Effekt derselbe, denn wenn n größer als eins ist, entspricht dies einigen weiteren Umdrehungen des schnellen Zeigers im Ring

class Solution {
    
    
public:
    ListNode *detectCycle(ListNode *head) {
    
    
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast != nullptr && fast->next != nullptr) {
    
    
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast) {
    
    
                ListNode* index1 = head;
                ListNode* index2 = fast;
                while (index1 != index2) {
    
    
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index1;
            }
        }
        return nullptr;
    }
};

Fügen Sie hier eine Bildbeschreibung ein

Zusammenfassen

Die heutige Ernte ist immer noch ziemlich groß. Diese kreisförmige verknüpfte Liste ist nicht schwierig, aber sehr interessant. Es fühlt sich ein bisschen an, als würde man eine Matheaufgabe schreiben. Es ist wirklich bequem, den Schleier Schritt für Schritt zu enthüllen ~

Supongo que te gusta

Origin blog.csdn.net/qq_72157449/article/details/131794474
Recomendado
Clasificación