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