I will upload all the source codes of the current force deduction questions to my code cloud warehouse, Let me see the warehouse
Write in front
First of all, I wish you a happy Carnival! This is our holiday
To pay tribute to 1024, today's force buckle series is no longer a question, but a combination of multiple questions
Also with our recent update content Dream linkage
Question 206: reverse linked list
Title Description
Give you the head node of the single linked list. Please reverse the linked list and return the reversed linked list.
For example:
1->2->3->4->5
We want to return 5 - > 4 - > 3 - > 2 - > 1
Thinking solution
We have two ways to solve this problem
Pointer inversion method
Let's have this linked list
We can think that to reverse the linked list, we can try to reverse the pointer
Reverse one by one until the end
Speaking of simplicity, we actually have to consider many details
- The topic is a single linked list. We can't directly find the previous node, so we need a pointer to the previous node of the current pointer
- After changing the pointer, we can't find the following node, so we need another pointer to point to the node behind the current pointer
So here we need three pointers, prev, cur and next
initialization:
prev points to null first, cur points to head, and next points to head - > next
Traversal method diagram:
End condition: when cur is empty, note that when cur is empty, the next cannot be moved, because this will lead to the error of null pointer dereference, which is described in the code
code implementation
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* reverseList(struct ListNode* head){ if(!head) return NULL;//Here is the case of an empty linked list struct ListNode* prev=NULL,*cur=head,*next=head->next; while(cur) { cur->next=prev; prev=cur; cur=next; if(next) next=next->next;//This is to judge whether cur goes to the end. If cur goes to the end, it cannot move next } return n1; }
Head insertion
We can redefine a linked list
We traverse the list from the beginning and insert the knot into the new list
Drawing solution
code implementation
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* reverseList(struct ListNode* head){ if(!head) return NULL; struct ListNode* newhead=NULL,*cur=head,*next=head->next; while(cur) { cur->next=newhead; newhead=cur; cur=next; if(next) { next=cur->next; } } return newhead; }
Middle node of 876 question linked list
Title Description
Given a non empty single linked list with head node, return the intermediate node of the linked list.
If there are two intermediate nodes, the second intermediate node is returned.
Solution:
This is a typical fast and slow pointer problem. Although the idea is relatively simple, it is really not easy to think of it (silent tears)
We know, what is the mathematical characteristic of a midpoint?
Above, we obviously have 2AC=AB
So we also use the midpoint feature
Define two pointers fast and slow, where fast takes two steps at a time and slow takes one step at a time
When fast moves towards the end or towards the penultimate node, the position pointed by slow is the midpoint
Why is it marked in yellow?
Because we have the case that the length of the linked list is odd and even
Similarly, we draw a graph to solve
This is the case with an even number of nodes
This is the case with an odd number of nodes
code implementation
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* middleNode(struct ListNode* head){ struct ListNode*fast=head,*slow=head; while(fast&&fast->next) { fast=fast->next->next; slow=slow->next; } return slow; }
Sword finger offer 22. The penultimate node in the linked list
Title Description
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.
Thinking solution
Because the single linked list can only go along, not backwards
So we think along this line, and we are also walking
This is also a double pointer problem
Follow the same question
We can let the fast pointer go k steps first to ensure that there is a difference of k distances between fast and slow
After fast takes k steps, slow and fast go at the same time
End condition: fast goes to the end of the linked list
graphic
code implementation
/** * struct ListNode { * int val; * struct ListNode *next; * }; */ /** * * @param pListHead ListNode class * @param k int integer * @return ListNode class */ struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) { // write code here struct ListNode* fast=pListHead,*slow=pListHead; while(k--) { if(!fast) { return NULL; } fast=fast->next; } while(fast) { fast=fast->next; slow=slow->next; } return slow; }
21 merge two ordered linked lists
Title Description
Merge the two ascending linked lists into a new ascending linked list and return. The new linked list is composed of all nodes of a given two linked lists.
Input: l1 = [1,2,4], l2 = [1,3,4]
Output: [1,1,2,3,4,4]
Thinking solution
This is similar to the merging idea of arrays. I'm here This blog As mentioned in
The idea is to define two pointers to two linked lists respectively, and then compare the size. Whoever is young will insert the tail into the new linked list we define.
The end condition is L1 and L2, one of the pointers points to null, and then directly link the remaining nodes
Here, in order to prevent various problems caused by the empty new linked list, we introduce a sentinel bit header node here
Drawing solution
code implementation
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){ if(!l1) return l2; if(!l2) return l1; //The above is actually a case where the linked list is empty struct ListNode* head=malloc(sizeof(struct ListNode));//Open header node struct ListNode* tail=head;//Defined for trailing while(l1&&l2) { if(l1->val<l2->val) { tail->next=l1; l1=l1->next; tail=tail->next; } else { tail->next=l2; l2=l2->next; tail=tail->next; } } if(!l1) { tail->next=l2; } if(!l2) { tail->next=l1; }//Link remaining elements struct ListNode* newhead=head->next; free(head); return newhead; }