[Code Random Record] Linked list

linked list

A linked list is a linear structure connected by pointers. Each node is composed of two parts, one is the data field and the other is the pointer field (stores the pointer to the next node), and the pointer field of the last node points to null (null pointer the meaning of).
1. Singly linked list

2. Double linked list (each node has two pointer fields, one pointing to the next node and one pointing to the previous node)
insert image description here
3. Circular linked list
insert image description here

  • define node
struct ListNode {
    
    
      int val;
      ListNode *next;
      ListNode() : val(0), next(nullptr) {
    
    }
      ListNode(int x) : val(x), next(nullptr) {
    
    }
      ListNode(int x, ListNode *next) : val(x), next(next) {
    
    }
  };


//1.通过自己定义的节点构造函数
ListNode* head = new ListNode(5);

//2.使用默认构造函数初始化节点:
ListNode* head = new ListNode();
head->val = 5;

1. Design linked list

707. Design Linked List

Design the implementation of linked list. You can choose to use a singly linked list or a doubly linked list. A node in a singly linked list should have two properties: valand next. valis the value of the current node, nextwhich is a pointer/reference to the next node. If you are using a doubly linked list, you also need a property prevto indicate the previous node in the linked list. Assume that all nodes in the linked list are 0-index.

Implement these functions in the linked list class:

  • get(index): Get the value of the indexth . Returns if the index is invalid -1.
  • addAtHead(val): Add a node valwhose . After insertion, the new node will be the first node of the linked list.
  • addAtTail(val): Append the node valwhose to the last element of the linked list.
  • addAtIndex(index,val): Add a node with the value before the indexth val. If indexequal to the length of the linked list, the node will be appended to the end of the linked list. If indexis greater than the length of the linked list, the node will not be inserted. If indexless than 0, the node is inserted at the head.
  • deleteAtIndex(index): If the index indexis valid , delete the indexth node in the linked list.

Setting up a virtual head node is relatively simple

1. Singly linked list

class MyLinkedList {
    
    
public:
    struct ListNoded{
    
    
        int val;
        ListNoded* next;
        ListNoded() : val(0),next(nullptr){
    
    }
        ListNoded(int x) : val(x),next(nullptr){
    
    }
        ListNoded(int x,ListNoded* next) : val(x),next(next){
    
    }
    };

    MyLinkedList() {
    
    
        head = new ListNoded(); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
        size = 0;
    }
    
    int get(int index) {
    
    
        if(index < 0 || index >= size){
    
    
            return -1;
        }
        else{
    
    
            ListNoded* curGetNode = head->next;
            for(int i = 0;i < index; i++){
    
    
                curGetNode = curGetNode->next;
            }
            return curGetNode->val;
        }
    }
    
    void addAtHead(int val) {
    
    
        ListNoded* newHead = new ListNoded(val);
        newHead->next = head->next;
        head->next = newHead;
        size++;
    }
    
    void addAtTail(int val) {
    
    
        ListNoded* newTail = new ListNoded(val);
        ListNoded* curAddTailNode = head;
        for(;curAddTailNode->next != nullptr;){
    
    
            curAddTailNode = curAddTailNode->next;
        }
        curAddTailNode->next = newTail;
        size++;
    }
    
    void addAtIndex(int index, int val) {
    
      
         if(index == size){
    
    
            addAtTail(val);
        }
        else if(index == 0){
    
    
            addAtHead(val);
        }
        else if(index < 0){
    
    
            addAtHead(0);
        }
        else if(index > size){
    
    
            return;
        }
        else{
    
    
            ListNoded* newIndex = new ListNoded(val); 
            ListNoded* curAddIndexNode = head;
            for(int i = 0;i < index;i++){
    
    
                curAddIndexNode = curAddIndexNode->next;
            }
            newIndex->next = curAddIndexNode->next;
            curAddIndexNode->next = newIndex;
            size++;
        }
    }
    
    void deleteAtIndex(int index) {
    
    
        if(index < 0 || index >= size){
    
    
            return;
        }
        else{
    
    
            ListNoded* curDeleteNode = head;
            for(int i = 0;i < index;i++){
    
    
                curDeleteNode = curDeleteNode->next;
            }
            ListNoded* temp = curDeleteNode->next;
            curDeleteNode->next = curDeleteNode->next->next;
            delete temp;
            size--;
        }
    }
private:
    int size;
    ListNoded* head;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

2. Doubly linked list

class MyLinkedList {
    
    
public:
    struct ListNoded{
    
    
        int val;
        ListNoded* next;
        ListNoded* prev;
        ListNoded() : val(0),next(nullptr),prev(nullptr){
    
    }
        ListNoded(int x) : val(x),next(nullptr),prev(nullptr){
    
    }
    };

    MyLinkedList() {
    
    
        head = new ListNoded(); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
        end = new ListNoded();
        head->next = end;
        end->prev = head;
        size = 0;
    }
    
    int get(int index) {
    
    
        if(index < 0 || index >= size){
    
    
            return -1;
        }
        else{
    
    
            ListNoded* curGetNode = head->next;
            for(int i = 0;i < index; i++){
    
    
                curGetNode = curGetNode->next;
            }
            return curGetNode->val;
        }
    }
    
    void addAtHead(int val) {
    
    
        ListNoded* newHead = new ListNoded(val);
        newHead->next = head->next;
        newHead->prev = head;
        head->next->prev = newHead;
        head->next = newHead;
        size++;
    }
    
    void addAtTail(int val) {
    
    
        ListNoded* newTail = new ListNoded(val);
        ListNoded* curAddTailNode = head;
        for(;curAddTailNode->next != end;){
    
    
            curAddTailNode = curAddTailNode->next;
        }
        newTail->next = curAddTailNode->next;
        newTail->prev = curAddTailNode;
        curAddTailNode->next->prev = newTail;
        curAddTailNode->next = newTail;
        size++;
    }
    
    void addAtIndex(int index, int val) {
    
      
         if(index == size){
    
    
            addAtTail(val);
        }
        else if(index == 0){
    
    
            addAtHead(val);
        }
        else if(index < 0){
    
    
            addAtHead(0);
        }
        else if(index > size){
    
    
            return;
        }
        else{
    
    
            ListNoded* newIndex = new ListNoded(val); 
            ListNoded* curAddIndexNode = head;
            for(int i = 0;i < index;i++){
    
    
                curAddIndexNode = curAddIndexNode->next;
            }
            newIndex->next = curAddIndexNode->next;
            newIndex->prev = curAddIndexNode;
            curAddIndexNode->next->prev = newIndex;
            curAddIndexNode->next = newIndex;
            size++;
        }
    }
    
    void deleteAtIndex(int index) {
    
    
        if(index < 0 || index >= size){
    
    
            return;
        }
        else{
    
    
            ListNoded* curDeleteNode = head;
            for(int i = 0;i < index;i++){
    
    
                curDeleteNode = curDeleteNode->next;
            }
            ListNoded* temp = curDeleteNode->next;
            curDeleteNode->next->next->prev = curDeleteNode;
            curDeleteNode->next = curDeleteNode->next->next;
            delete temp;
            size--;
        }
    }
private:
    int size;
    ListNoded* head;
    ListNoded* end;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

2. Changed a little bit to make prev useful

class MyLinkedList {
    
    
public:
    struct ListNoded{
    
    
        int val;
        ListNoded* next;
        ListNoded* prev;
        ListNoded() : val(0),next(nullptr),prev(nullptr){
    
    }
        ListNoded(int x) : val(x),next(nullptr),prev(nullptr){
    
    }
    };

    MyLinkedList() {
    
    
        head = new ListNoded(); // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点
        end = new ListNoded();
        head->next = end;
        end->prev = head;
        size = 0;
    }
    
    int get(int index) {
    
    
        if(index < 0 || index >= size){
    
    
            return -1;
        }
        else if(index <= (size - 1) / 2){
    
    
            ListNoded* curGetNode = head->next;
            for(int i = 0;i < index; i++){
    
    
                curGetNode = curGetNode->next;
            }
            return curGetNode->val;
        }
        else{
    
    
            ListNoded* curGetNode = end->prev;
            index = size - index - 1;//从后往前查找,查找次数要变
            for(int i = 0;i < index; i++){
    
    
                curGetNode = curGetNode->prev;
            }
            return curGetNode->val;
        }
    }
    
    void addAtHead(int val) {
    
    
        ListNoded* newHead = new ListNoded(val);
        newHead->next = head->next;
        newHead->prev = head;
        head->next->prev = newHead;
        head->next = newHead;
        size++;
    }
    
    void addAtTail(int val) {
    
    
        ListNoded* newTail = new ListNoded(val);
        ListNoded* curAddTailNode = head;
        for(;curAddTailNode->next != end;){
    
    
            curAddTailNode = curAddTailNode->next;
        }
        newTail->next = curAddTailNode->next;
        newTail->prev = curAddTailNode;
        curAddTailNode->next->prev = newTail;
        curAddTailNode->next = newTail;
        size++;
    }
    
    void addAtIndex(int index, int val) {
    
      
         if(index == size){
    
    
            addAtTail(val);
        }
        else if(index == 0){
    
    
            addAtHead(val);
        }
        else if(index < 0){
    
    
            addAtHead(0);
        }
        else if(index > size){
    
    
            return;
        }
        else if(index <= (size - 1) / 2){
    
    
            ListNoded* newIndex = new ListNoded(val); 
            ListNoded* curAddIndexNode = head;
            for(int i = 0;i < index;i++){
    
    
                curAddIndexNode = curAddIndexNode->next;
            }
            newIndex->next = curAddIndexNode->next;
            newIndex->prev = curAddIndexNode;
            curAddIndexNode->next->prev = newIndex;
            curAddIndexNode->next = newIndex;
            size++;
        }
        else{
    
    
            ListNoded* newIndex = new ListNoded(val); 
            ListNoded* curAddIndexNode = end;
            index = size - index;//!!!因为是要插入新节点到index的前面,所以新节点插入位置的前一个位置是index-1,后一个位置是index。所以从左往右遍历时,遍历到index-1的位置;从右往左遍历时,遍历到index(而不是index+1)。注意这点不同。
            for(int i = 0;i < index;i++){
    
    
                curAddIndexNode = curAddIndexNode->prev;
            }
            newIndex->prev = curAddIndexNode->prev;
            newIndex->next = curAddIndexNode;
            curAddIndexNode->prev->next = newIndex;
            curAddIndexNode->prev = newIndex;
            size++;
        }
    }
    
    void deleteAtIndex(int index) {
    
    
        if(index < 0 || index >= size){
    
    
            return;
        }
        else if(index <= (size - 1) / 2){
    
    
            ListNoded* curDeleteNode = head;
            for(int i = 0;i < index;i++){
    
    
                curDeleteNode = curDeleteNode->next;
            }
            ListNoded* temp = curDeleteNode->next;
            curDeleteNode->next->next->prev = curDeleteNode;
            curDeleteNode->next = curDeleteNode->next->next;
            delete temp;
            size--;
        }
        else{
    
    
            ListNoded* curDeleteNode = end;
            index = size - index - 1;//指向待删除节点的后一个位置,所以减1
            for(int i = 0;i < index;i++){
    
    
                curDeleteNode = curDeleteNode->prev;
            }
            ListNoded* temp = curDeleteNode->prev;
            curDeleteNode->prev->prev->next = curDeleteNode;
            curDeleteNode->prev = curDeleteNode->prev->prev;
            delete temp;
            size--;
        }
    }
private:
    int size;
    ListNoded* head;
    ListNoded* end;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

2. Remove the linked list element

insert image description here

  • Remember to delete to delete the node

203. Remove linked list elements

Given a head node of a linked list headand an integer val, please delete all nodes Node.val == valsatisfying and return a new head node .

1. Method 1: Use the original linked list directly to delete

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* removeElements(ListNode* head, int val) {
    
    
        ListNode* deleteNode;
        while(head != NULL && head->val == val){
    
    
                deleteNode = head;
                head = head->next;
                delete deleteNode;
            }
        ListNode* current = head;
        while(current != NULL && current->next != NULL){
    
    
            if(current->next->val == val){
    
    
                deleteNode = current->next;
                current->next = current->next->next;
                delete deleteNode;
            } 
            else{
    
    
                current = current->next;
            }         
        } 
        return head;
    }
};

2. Method 2: Set a virtual head node to remove the node:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* removeElements(ListNode* head, int val) {
    
    
        ListNode* virNode = new ListNode(0,head);
        ListNode* currentNode = virNode;
        while(currentNode->next != NULL){
    
    
            if(currentNode->next->val == val){
    
    
                ListNode* deleteNode = currentNode->next;
                currentNode->next = currentNode->next->next;
                delete deleteNode;
            }
            else{
    
    
                currentNode = currentNode->next;
            }
        }
        head = virNode->next;
        delete virNode;
        return head;
    }
};

3. Method 3: **Recursion**

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* removeElements(ListNode* head, int val) {
    
    
        if(head == NULL){
    
    
            return head;
        }
        else{
    
    
            head->next = removeElements(head->next,val);
            if(head->val == val){
    
    
                return head->next;
            }
            else{
    
    
                return head;
            }
        }
    }
};

3. Flip the linked list

206. Reverse Linked List

Given the head node of the singly linked list head, please reverse the linked list and return the reversed linked list.

img

1.双指针法
```
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* reverseList(ListNode* head) {
    
    
        ListNode* slowNode = NULL;
        ListNode* fastNode = head;
        ListNode* curNode;
        while(fastNode != NULL){
    
    
            curNode = fastNode;
            fastNode = fastNode->next;
            curNode->next = slowNode;
            slowNode = curNode;
        }
    return slowNode;
    }
};

2. Recursion 1

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* reverse(ListNode* slowNode,ListNode* fastNode){
    
    
        if(fastNode == NULL) return slowNode;
        ListNode* curNode;
        curNode = fastNode;
        fastNode = fastNode->next;
        curNode->next = slowNode;
        slowNode = curNode;
        return reverse(slowNode,fastNode);
    }

    ListNode* reverseList(ListNode* head) {
    
    
        ListNode* slowNode = NULL;
        ListNode* fastNode = head;
        return reverse(slowNode,fastNode);
    }
};

3. Recursion 2

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* reverseList(ListNode* head) {
    
    
        if(head == nullptr) return nullptr;
        if(head->next == nullptr) return head;
        ListNode* last = reverseList(head->next);
        head->next->next = head;
        head->next = nullptr;
        return last;
    }
};

Recursive methods still need to learn

4. Exchange the nodes in the linked list in pairs

24. Exchange the nodes in the linked list two by two

Given a linked list, exchange the adjacent nodes in it two by two, and return the head node of the exchanged linked list. You must complete this exercise without modifying the values ​​inside the nodes (i.e. only node swaps).

img

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* swapPairs(ListNode* head) {
    
    
        ListNode* virNode = new ListNode(0,head);
        if(head == nullptr || head->next == nullptr) return head;
        ListNode* slowNode = virNode;
        ListNode* fastNode = head;
        ListNode* curSlow,*curFast;
        while(fastNode != NULL && fastNode->next != NULL){
    
    //双数fastNode不能等于NULL,单数fastNode->next不能等于NULL
            curSlow = slowNode;
            curFast = fastNode;

            fastNode = fastNode->next->next;

            curSlow->next = curFast->next;
            curFast->next->next = curFast;
            curFast->next = fastNode;
            
            slowNode = curFast;
        }
        head = virNode->next;
        delete virNode;
        return head;
    }
};

5. Delete the last N node of the linked list

19. Delete the last N node of the linked list

Given a linked list, delete the npenultimate , and return the head node of the linked list.

img

1. Brute force cracking

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
    
    
        ListNode* virNode = new ListNode(0,head);
        ListNode* curNode = virNode;
        int index = 0;
        if(head == nullptr || head->next == nullptr)return nullptr;
        while(curNode->next != nullptr){
    
    //统计个数
            curNode = curNode->next;
            index++;
        }
        curNode = virNode;
        for(int i = 0;i < index - n;i++){
    
    //删除
            curNode = curNode->next;
        }
        ListNode* deleteNode = curNode->next;
        curNode->next = curNode->next->next;
        delete deleteNode;
        head = virNode->next;
        delete virNode;
        return head;
    }
};

2. Double pointer (mirror image, find the symmetrical point to be deleted, and then move the two pointers back at the same time, so that the slow pointer points to the one before the deletion point)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
    
    
        ListNode* virNode = new ListNode(0,head);
        ListNode* slowNode = virNode;
        ListNode* fastNode = virNode;
        if(head == nullptr || head->next == nullptr)return nullptr;
        while(fastNode != nullptr && n){
    
    //利用对称思想,找到对称过来要删除的点,然后将两个指针同时往后移,使慢指针指向删除点前一位
            fastNode = fastNode->next;
            n--;
        }
        while(fastNode->next != nullptr){
    
    
            slowNode = slowNode->next;
            fastNode = fastNode->next;
        }
        ListNode* deleteNode = slowNode->next;
        slowNode->next = slowNode->next->next;
        delete deleteNode;
        return virNode->next;
    }
};

6. Linked list intersect

  • Intersection is not numerical equality, but pointer equality

Interview Question 02.07. Linked List Intersection

Given the head nodes headAand headB, please find and return the starting node where the two singly linked lists intersect. If there is no intersection between the two linked lists, return null.

The illustration shows that two linked lists c1intersect **:**

img

Topic data Guarantee that there is no cycle in the entire chain structure.

Note that after the function returns the result, the linked list must maintain its original structure

1. Violent for loop

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
        for(ListNode* curA = headA;curA != NULL;curA = curA->next){
    
    
            for(ListNode* curB = headB;curB != NULL;curB = curB->next){
    
    
                if(curA == curB)return curA;
            }
        }
        return NULL;
    }
};

2. According to the idea of ​​random recording of the code, it is very clever, assuming that A is longer than B, remove the part in front of it, and see if there is any overlap in the back

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
        ListNode* curA = headA;
        ListNode* curB = headB;
        int indexA = 0;
        int indexB = 0;
        while(curA != NULL){
    
    
            curA = curA->next;
            indexA++;
        }
        while(curB != NULL){
    
    
            curB = curB->next;
            indexB++;
        }

        curA = headA;
        curB = headB;//重新到开头
        
        if(indexA >= indexB) {
    
    
            int cha = indexA - indexB;
            while(cha--){
    
    
                curA = curA->next;
            }
            while(curA != NULL || curB != NULL){
    
    
                if(curA == curB)return curA;
                curA = curA->next;
                curB = curB->next;
            }
        }
        else{
    
    
            int cha = indexB - indexA;
            while(cha--){
    
    
                curB = curB->next;
            }
            while(curA != NULL || curB != NULL){
    
    
                if(curA == curB)return curA;
                curA = curA->next;
                curB = curB->next;
            }
        }
        return NULL;
    }
};

3. Further improvement

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
        ListNode* curA = headA;
        ListNode* curB = headB;
        int indexA = 0;
        int indexB = 0;
        while(curA != NULL){
    
    
            curA = curA->next;
            indexA++;
        }
        while(curB != NULL){
    
    
            curB = curB->next;
            indexB++;
        }
        
        if(indexB > indexA){
    
    
            swap(headA,headB);
            swap(indexA,indexB);
        }

        curA = headA;
        curB = headB;//重新到开头
        
        int cha = indexA - indexB;
        while(cha--){
    
    
            curA = curA->next;
        }
        while(curA != NULL || curB != NULL){
    
    
            if(curA == curB)return curA;
            curA = curA->next;
            curB = curB->next;
        }
        return NULL;
    }
};

7. Ring linked list

142. Circular Linked List II

Given the head node of a linked list head, return the first node where the linked list starts entering the ring. Returns if the linked list is acyclic null.

If there is a node in the linked list that can be reached again by continuously tracking nextthe 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 an integer posto indicate the position where the end of the linked list is connected to the linked list ( the index starts from 0 ). If posyes -1, there are no cycles in the linked list. Note: posIt is not passed as a parameter , just to identify the actual situation of the linked list.

Modification of the linked list is not allowed.

Example 1:

img

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

1. Add hints with your own ideas (read a hint, let the fast pointer and the slow pointer proceed at the same time, but the fast pointer is faster than the slow pointer)

After thinking for a long time, this hint is the key to solving the problem

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode *detectCycle(ListNode *head) {
    
    
        ListNode* virHead = new ListNode(0,head);
        ListNode* slowNode = virHead;
        ListNode* fastNode = virHead;
        ListNode* findNode = virHead;//查找入口
        while(fastNode != NULL && fastNode->next != NULL){
    
    
            slowNode = slowNode->next;//要快指针比慢指针走得快一些看他们能不能相遇
            fastNode = fastNode->next->next;
            if(slowNode == fastNode){
    
         
                while(fastNode != findNode){
    
    //一直循环,每次绕到原来跟慢指针一样位置为一圈,查找入口位置
                    fastNode = fastNode->next;
                    if(fastNode == slowNode){
    
    
                        findNode = findNode->next;
                    }
                }
                return findNode;
            }
        }
        return NULL;
    }
};

2. According to the idea of ​​code random recording, draw a picture and use mathematical methods to solve
it

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    ListNode *detectCycle(ListNode *head) {
    
    
        ListNode* virHead = new ListNode(0,head);
        ListNode* slowNode = virHead;
        ListNode* fastNode = virHead;
        ListNode* findNode = virHead;//查找入口
        while(fastNode != NULL && fastNode->next != NULL){
    
    
            slowNode = slowNode->next;//要快指针比慢指针走得快一些看他们能不能相遇
            fastNode = fastNode->next->next;
            if(slowNode == fastNode){
    
         
                while(fastNode != findNode){
    
    //根据代码随想录数学公式
                    fastNode = fastNode->next;
                    findNode = findNode->next;
                }
                return findNode;
            }
        }
        return NULL;
    }
};

Guess you like

Origin blog.csdn.net/m0_53953432/article/details/128064120