Sword finger offer (C + +) -- linked list collection

Posted by vcarter on Sun, 23 Jan 2022 07:00:44 +0100

This series of notes is for self-study algorithm. It only records the problem solving code and some problem solving ideas. All topics are copyrighted by LeeCode and sword finger offer; We recommend a great series of blog for brushing questions and taking notes, which can be used as a reference for the classification of questions in this series: Summary of Jianzhi Offer series question brushing notes

Note: the title serial number is shown here Official website The ranking in shall prevail, or it is different from other references;

6. Output linked list from end to end

Enter the head node of a linked list, and return the value of each node from tail to head (returned by array).

Input: head = [1,3,2]
Output: [2,3,1]

Limitations:

0 < = linked list length < = 10000

answer:

class Solution {    //recursion
    vector<int> res;
public:
    vector<int>& reversePrint(ListNode* head) {     //Note: the return value is a reference, which reduces a large number of memory copies
        if(head == NULL)    return res;
        reversePrint(head->next);
        res.push_back(head->val);
        return res;
    }
};

class Solution {    //Array flip
public:
    vector<int> reversePrint(ListNode* head) {
        vector<int> res;
        while(head)
        {
            res.push_back(head->val);
            head = head->next;
        }
        reverse(res.begin(), res.end());
        return res;
    }
};

class Solution {    //Use stack
public:
    vector<int> reversePrint(ListNode* head) {
        vector<int> res;
        stack<int> s;
        ListNode* node = head;//Do not change the original header pointer
        while(node)
        {
            s.push(node->val);
            node = node->next;
        }
        while(!s.empty())
        {
            res.push_back(s.top());
            s.pop();
        }
        return res;
    }
};
//Author: zrita
//Link: https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/solution/c-san-chong-fang-fa-z-by-zrita-7ctq/
18. Delete linked list node

Given the head pointer of the one-way linked list and the value of a node to be deleted, define a function to delete the node.
Returns the head node of the deleted linked list.
Note: this question is different from the original one

Input: head = [4,5,1,9], val = 5
Output: [4,1,9]
Explanation: given the second node with a value of 5 in your linked list, after calling your function, the linked list should be 4 - > 1 - > 9

answer:

class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
        if(head->val == val) return head->next;//Deleting the first node
        ListNode *pre = head, *cur = head->next;
        while(cur != nullptr && cur->val != val) {
            pre = cur;
            cur = cur->next;//Traverse the deleted node location
        }
        if(cur != nullptr) pre->next = cur->next;//Delete this node
        return head;
    }
};

//Author: jyd
//Link: https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/solution/mian-shi-ti-18-shan-chu-lian-biao-de-jie-dian-sh-2/
22 the penultimate node in the linked list

Input a linked list and output the penultimate node in the linked list. In order to conform to the habit of most people, this question starts from 1, that is, the tail node of the linked list is the penultimate node.
For example, a linked list has six nodes. Starting from the beginning, their values are 1, 2, 3, 4, 5 and 6. The penultimate node of the linked list is a node with a value of 4.

Given a linked list: 1 - > 2 - > 3 - > 4 - > 5, and k = 2
Return to linked list 4 - > 5

answer:

class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        // Excluding input is null pointer and K < = 0 is meaningless
        if (head == nullptr || k <= 0) 
            return nullptr;
        ListNode* fast = head, * slow = head;
        for (int i = 0; i < k; i ++){
            // Exclude the case where the k value is greater than the length of the linked list
            if (fast == nullptr)
                return nullptr;
            fast = fast->next;
        }
        while (fast != nullptr){
            fast = fast->next;
            slow = slow->next;
        }
        return slow;
    }
};

//Author: master_xue
//Link: https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/solution/kao-lu-dai-ma-de-lu-bang-xing-cai-shi-be-7c5b/
24. Reverse linked list

Define a function, input the head node of a linked list, invert the linked list and output the head node of the inverted linked list.

Input: 1 - > 2 - > 3 - > 4 - > 5 - > null
Output: 5 - > 4 - > 3 - > 2 - > 1 - > null

answer:

class Solution {    //Change the direction of two adjacent nodes at a time
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* temp; // Save the next node of cur
        ListNode* pre = NULL;
        ListNode* cur = head;
        while(cur) {
            temp = cur->next;  // Save the next node of cur, and then change cur - > next
            cur->next = pre; // Flip linked list direction operation
            // Update pre and cur pointers
            pre = cur;
            cur = temp;
        }
        return pre;
    }
};

//Author: carlsun-2
//Link: https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/solution/fan-zhuan-lian-biao-shuang-zhi-zhen-fa-d-7stu/
25. Merge sort linked list

Enter two incrementally sorted linked lists, merge the two linked lists and make the nodes in the new linked list still incrementally sorted.

Input: 1->2->4, 1->3->4
 Output: 1->1->2->3->4->4
 Limitations:
0 <= Linked list length <= 1000

answer:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {    //Non recursive solution
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* head = new ListNode(0);  //New linked list
        ListNode* cur = head;
        while (l1 && l2) {
            if (l1->val < l2->val) {
                cur->next = l1;
                l1 = l1->next;
            } else {
                cur->next = l2;
                l2 = l2->next;
            }
            cur = cur->next;  //Merge one at a time
        }
        if (l1) cur->next = l1;  //The last l2 is empty
        else cur->next = l2;  //The last l1 is empty
        return head->next;
    }
};
class Solution {    //Recursive solution
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (!l1 || !l2) return !l1 ? l2 : l1;  //One of the linked lists is empty
        if (l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);
            return l1;
        } else {
            l2->next = mergeTwoLists(l1, l2->next);
            return l2;
        }
    }
};
//Author: moreality
//Link: https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/solution/c-di-gui-he-fei-di-gui-jie-fa-by-moreali-7f4b/

class Solution {    //Another recursive merging method
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        //Judge whether the pointer is empty
        if(pHead1 == NULL){
            return pHead2;
        }
        else if(pHead2 == NULL){
            return pHead1;
        }
        ListNode* pMergedHead = NULL;
        if(pHead1->val < pHead2->val){
            pMergedHead = pHead1;
               pMergedHead->next = Merge(pHead1->next, pHead2);
        }
        else{
            pMergedHead = pHead2;
               pMergedHead->next = Merge(pHead1, pHead2->next);
        }
        return pMergedHead;
    }
};
//come from: https://cuijiahua.com/blog/2017/12/basis_16.html
35. Replication of complex linked list

Please implement the copyRandomList function to copy a complex linked list. In a complex linked list, each node has a next pointer to the next node and a random pointer to any node or null in the linked list.

Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]

Tips:
-10000 <= Node.val <= 10000
Node.random is empty (null) or points to a node in the linked list.
The number of nodes shall not exceed 1000.

answer:

Copy the new node on the original linked list and split the even number node into a new chain
Insert picture description here

class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(head == nullptr) return nullptr;
        Node* cur = head;
        // 1. Copy each node and build a splicing linked list
        while(cur != nullptr) {
            Node* tmp = new Node(cur->val);
            tmp->next = cur->next;
            cur->next = tmp;
            cur = tmp->next;
        }
        // 2. Build the random direction of each new node
        cur = head;
        while(cur != nullptr) {
            if(cur->random != nullptr)
                cur->next->random = cur->random->next;
            cur = cur->next->next;
        }
        // 3. Split two linked lists
        cur = head->next;
        Node* pre = head, *res = head->next;
        while(cur->next != nullptr) {
            pre->next = pre->next->next;
            cur->next = cur->next->next;
            pre = pre->next;
            cur = cur->next;
        }
        pre->next = nullptr; // Handle the original end node of the linked list separately
        return res;      // Return to the new chain header node
    }
};

//Author: jyd
//Link: https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/solution/jian-zhi-offer-35-fu-za-lian-biao-de-fu-zhi-ha-xi-/
52. Common node of two linked lists

Enter two linked lists and find their first common node.

Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
Output: Reference of the node with value = 8
Input explanation: the value of intersection node is 8 (note that if two lists intersect, it cannot be 0). Starting from their 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.

be careful:
If two linked lists have no intersection, null is returned
After returning the results, the two linked lists must still maintain their original structure.
It can be assumed that there is no loop in the whole linked list structure.
The program shall meet the O(n) time complexity as much as possible, and only use O(1) memory.

answer:

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* curA = headA;
        ListNode* curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != NULL) { // Find the length of linked list A
            lenA++;
            curA = curA->next;
        }
        while (curB != NULL) { // Find the length of linked list B
            lenB++;
            curB = curB->next;
        }
        curA = headA;
        curB = headB;
        // Let curA be the head of the longest linked list and lenA be its length
        if (lenB > lenA) {
            swap (lenA, lenB);
            swap (curA, curB);
        }
        // Length difference
        int gap = lenA - lenB;
        // Make curA and curB at the same starting point (align the end position)
        while (gap--) {
            curA = curA->next;
        }
        // Traverse curA and curB, and return directly in case of the same
        while (curA != NULL) {
            if (curA == curB) {
                return curA;
            }
            curA = curA->next;
            curB = curB->next;
        }
        return NULL;
    }
};

//Author: carlsun-2
//Link: https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/solution/dai-ma-sui-xiang-lu-liang-ge-lian-biao-d-i0tx/
Attachment 1 - entry node of link in linked list

A linked list contains links. Please find the entry node of the link in the linked list.

answer:

Determine how many nodes there are in the ring
You can use fast and slow pointers, one step at a time and two steps at a time. If two pointers meet, it indicates that there is a ring in the linked list, and the node where the two pointers meet must be in the ring.
Then, we start from the node in the ring we meet, move forward and count. When we return to this node again, we can get the number of nodes in the ring.

If the ring in the linked list has n nodes, the pointer P1 first moves forward n steps on the linked list, and then the two pointers move forward at the same speed. Until they meet, when the second pointer points to the entry node, the first pointer has beaten around and returned to the entry node.. The node they meet is exactly the entrance node of the ring

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if(pHead == NULL){
            return NULL;
        }
        ListNode* meetingnode = MeetingNode(pHead);
        if(meetingnode == NULL){
            return NULL;
        }
        // Number of loopback list nodes
        int nodesloop = 1;
        // Find the number of nodes in the ring
        ListNode* pNode1 = meetingnode;
        while(pNode1->next != meetingnode){
            pNode1 = pNode1->next;
            nodesloop++;
        }
        pNode1 = pHead;
        // The first pointer moves the nodesloop step forward
        for(int i = 0; i < nodesloop; i++){
            pNode1 = pNode1->next;
        }
        // Move the two pointers at the same time to find the ring entrance
        ListNode* pNode2 = pHead;
        while(pNode1 != pNode2){
            pNode1 = pNode1->next;
            pNode2 = pNode2->next;
        }
        return pNode1;
    }
private:
    // Use the speed pointer to find any node in the ring
    ListNode* MeetingNode(ListNode* pHead){
        ListNode* pSlow = pHead->next;
        if(pSlow == NULL){
            return NULL;
        }
        ListNode* pFast = pSlow->next;
        while(pFast != NULL && pSlow != NULL){
            if(pFast == pSlow){
                return pFast;
            }
            pSlow = pSlow->next;
            pFast = pFast->next;
            if(pFast != NULL){
                pFast = pFast->next;
            }
        }
        return NULL;
    }
};
//come from: https://cuijiahua.com/blog/2018/01/basis_55.html
Attachment 2 - delete duplicate nodes in the linked list

In a sorted linked list, there are duplicate nodes. Please delete the duplicate nodes in the linked list. The duplicate nodes are not retained and the chain header pointer is returned. For example, the linked list 1 - > 2 - > 3 - > 3 - > 4 - > 4 - > 5 is 1 - > 2 - > 5 after processing.

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        if(pHead == NULL){
            return NULL;
        }
        // Point to the latest non duplicate node accessed before the current node
        ListNode* pPre = NULL;
        // Point to the currently processed node
        ListNode* pCur = pHead;
        // Point to the node behind the current node
        ListNode* pNext = NULL;
        
        while(pCur != NULL){
            // If the current node is the same as the next node
            if(pCur->next != NULL && pCur->val == pCur->next->val){
                pNext = pCur->next;
                // Find the last node location that is not repeated
                while(pNext->next != NULL && pNext->next->val == pCur->val){
                    pNext = pNext->next;
                }
                // If pCur points to the first element in the linked list, pCur - >... - > pNext ->... 
                // To delete pCur to pNext, point the pointer pHead to the first element of the linked list to pNext - > next.
                if(pCur == pHead){
                    pHead = pNext->next;
                }
                // If pCur does not point to the first element in the linked list, ppre - > pCur - >... - > pNext ->... 
                // To delete pCur to pNext, that is, ppre - > next = pNext - > next
                else{
                    pPre->next = pNext->next;
                }
                // Move forward
                pCur = pNext->next;
            }
            // If the current node is different from the next node
            else{
                pPre = pCur;
                pCur = pCur->next;
            }
        }
        return pHead;
    }
};
//come from: https://cuijiahua.com/blog/2018/01/basis_56.html

Topics: C++ Algorithm data structure