[Code Caprice | Leetcode | Day 7] Linked List | Linked List Intersection | Ring Linked List II

foreword

Welcome to Little K 's Leetcode|Code Caprice|Thematic column, today I will bring you the sharing of linked list intersection and circular linked list II✨


Interview Question 02.07. Linked List Intersection

✨The topic link click here

Given the head nodes headA and headB of two singly linked lists, please find and return the starting node where the two singly linked lists intersect. Returns null if the two linked lists do not intersect.

Show that two linked lists intersect starting at node c1:

insert image description here

The title data guarantees that there are no loops in the entire chain structure.
Note that the linked list must maintain its original structure after the function returns the result.

Example 1:

Input : intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 Output
: Intersected at '8'
Explanation : The value of the intersected node is 8 (note that if two linked lists intersect, it cannot be 0).
Counting from the respective headers, linked list A is [4,1,8,4,5], and linked list B is [5,0,1,8,4,5].
In A, there are 2 nodes before the intersection node; in B, there are 3 nodes before the intersection node.

Example 2:

Input : intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 Output
: Intersected at '2'
Explanation : The value of the intersected node is 2 (note that it cannot be 0 if the two linked lists intersect).
Counting from the respective headers, linked list A is [0,9,1,2,4], and linked list B is [3,2,4].
In A, there are 3 nodes before the intersection node; in B, there is 1 node before the intersection node.

Example 3:

Input : intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
Output : null
Explanation : Counting from the respective headers, linked list A is [2,6,4], and linked list B is [1,5].
Since the two linked lists are disjoint, intersectVal must be 0, while skipA and skipB can be any value.
The two linked lists are disjoint, so null is returned.

hint:

The number of nodes in listA is m
The number of nodes in listB is n

0 <= < m, n= 3 * 104
1 <= Node.val<= 105
0 <= skipA<= m
0 <= skipB<= nIf there is no intersection with and is 0
If there is an intersection, the idea: This question is also a usage of double pointers. We first define two pointers to point to the head nodes of the two linked lists, and then let the pointer pointing to the longer linked list move backwards, align with the pointer of the shorter linked list, and finally It is moving, cyclic comparison, returning the first two pointers pointing to the same node, and returning empty if not foundlistA 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;
    }
};

insert image description here

142. Circular Linked List II

✨Title link here
Given a head node head of a linked list, return the first node of the linked list starting to enter the ring. Returns null if the linked list is acyclic. If there is a node in the linked list that can be reached again by continuously tracking the next pointer, then there is a cycle in the linked list. In order to represent the ring in the given linked list, the evaluation system internally uses the integer pos to indicate the position where the end of the linked list is connected to the linked list (the index starts from 0). If pos is -1, there are no cycles in the list. Note: pos is not passed as a parameter, it is just to identify the actual situation of the linked list.
The linked list is not allowed to be modified.

Example 1:
insert image description here

Input : head = [3,2,0,-4], pos = 1
Output : Return the linked list node with index 1
Explanation : There is a ring in the linked list, whose tail is connected to the second node.

Example 2:
insert image description here

Input : head = [1,2], pos = 0
Output : Return the linked list node with index 0
Explanation : There is a ring in the linked list, whose tail is connected to the first node.

Example 3:
insert image description here

Input : head = [1], pos = -1
Output : return null
Explanation : There is no ring in the linked list.

hint:
The number of nodes in the linked list is in the range [0, 104]
-105 <= Node.val<= 105
The value of pos is -1 or a valid index in the linked list

Idea: To solve this problem, we need to clarify the following two problems

  • Determine whether a linked list has a cycle
  • If there is a ring, how to find the entrance to this ring

Question 1: Determine whether the linked list has a ring

You can use the fast and slow pointer method to define a fast pointer fast and a slow pointer slow. Starting from the head node, let the fast pointer move two nodes each time, and the slow pointer move one node each time. If they meet on the way, it means that there is a cycle

Encounters must meet within the ring, why is this? The fast pointer must enter the ring before the slow pointer.
Why do the fast and slow pointers always meet? The fast pointer moves two steps at a time, and the slow pointer moves one step at a time, so the fast pointer is equivalent to catching up with the slow pointer one step at a time, so they will definitely meet

insert image description here

Question 2: Find the entrance of the ring

Suppose the number of nodes from the head node to the ring entry node is x. The number of nodes from the ring entry node to the node where the fast pointer meets the slow pointer is y. The number of nodes from the encounter node to the ring entry node is z.
Then when they meet: the number of nodes that the slow pointer has passed is: x + y, the number of nodes that the fast pointer has passed: , n is thex + y + n (y + z) fast pointer has walked n circles in the ring before encountering the slow pointer, and is the number of (y+z)nodes in one circle. low pointer.

When n is equal to one and greater than one, the effect is the same, because when n is greater than one, it is equivalent to a few more turns of the fast pointer in the 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;
    }
};

insert image description here

Summarize

Today’s harvest is still quite big. This circular linked list is not difficult, but it is very interesting. It feels a bit like writing a math problem. It is really comfortable to unveil the veil step by step~

Guess you like

Origin blog.csdn.net/qq_72157449/article/details/131794474