1, Title
1. Title Description
give a single linked list
L
L
Head node of L
h
e
a
d
head
head, single linked list
L
L
L is expressed as:
L
0
→
L
1
→
.
.
.
→
L
n
−
1
→
L
n
L_0 \to L_1 \to ... \to L_{n-1} \to L_n
L0 → L1 →... → Ln − 1 → Ln please rearrange them to:
L
0
→
L
n
→
L
1
→
L
n
−
1
→
L
2
→
L
n
−
2
→
.
.
.
L_0 \to L_n \to L1 \to L_{n-1} \to L_2 \to L_{n-2} \to ...
L0 → Ln → L1 → Ln − 1 → L2 → Ln − 2 →... You can't just change the internal value of the node, but you need to actually exchange nodes.
sample input: head = [1,2,3,4,5,6,7]
sample output: [1,7,2,6,3,5,4]
2. Basic framework
- The basic framework code given in the C language version is as follows:
void reorderList(struct ListNode* head) { }
3. Original question link
LeetCode 143. Rearrange linked list
Sword finger Offer II 026. Rearrange linked list
2, Problem solving Report
1. Train of thought analysis
1) first, use the speed pointer to disassemble the linked list into two linked lists. The first linked list is the first half and the second linked list is the second half;
2) then, flip the second linked list;
3) finally, merge the two linked lists.
2. Time complexity
all three steps are O ( n ) O(n) O(n) and are independent parts of each other.
3. Code explanation
// Odd number: L1 - > L2 - > L3 returns L2 // Even number: L1 - > L2 returns L2 struct ListNode* getHalf(struct ListNode* head) { struct ListNode *prev, *slow, *fast, *half; if(head == NULL) { return head; } prev = NULL; slow = head; fast = head; while(fast && fast->next) { prev = slow; slow = slow->next; fast = fast->next->next; } half = slow; if(prev) prev->next = NULL; return half; } struct ListNode *removeNextAndReturn(struct ListNode* now) { // (1) struct ListNode *retNode; if(now == NULL || now->next == NULL) { return NULL; // (2) } retNode = now->next; // (3) now->next = now->next->next; // (4) return retNode; } struct ListNode* reverseList(struct ListNode* head) { struct ListNode *newHead; struct ListNode *doRemoveNode = head; // (5) while(doRemoveNode) { // (6) newHead = removeNextAndReturn(doRemoveNode); // (7) if(newHead) { // (8) newHead->next = head; head = newHead; }else { break; // (9) } } return head; } struct ListNode* merge(struct ListNode* a, struct ListNode* b) { struct ListNode* tmp; if(a == NULL) { return b; } tmp = a->next; // (10) a->next = b; // (11) b->next = merge(tmp, b->next); // (12) return a; } void reorderList(struct ListNode* head){ struct ListNode* half = getHalf(head); if(head == half) return head; // (13) half = reverseList(half); // (14) merge(head, half); // (15) }
- ( 1 ) (1) (1) Delete the next node of now and return
- ( 2 ) (2) (2) If the node itself is empty or the next node is empty, null is returned
- ( 3 ) (3) (3) Cache the nodes to be deleted for subsequent return
- ( 4 ) (4) (4) Delete now - > next
- ( 5 ) (5) (5) doRemoveNode - > next is the node to be deleted, so doRemoveNode needs to be cached, otherwise you don't know how to delete it
- ( 6 ) (6) (6) There are no nodes to delete
- ( 7 ) (7) (7) Delete the next node of doRemoveNode and return the deleted node
- ( 8 ) (8) (8) If there is a deleted node, insert the header
- ( 9 ) (9) (9) If not, jump out of the iteration
- ( 10 ) (10) (10) Simply cache it
- ( 11 ) (11) (11) Point a to b
- ( 12 ) (12) (12) Point b to the combined result of a - > next and b - > next
- ( 13 ) (13) (13) There is only one element
- ( 14 ) (14) (14) Perform linked list inversion
- ( 15 ) (15) (15) Merge two linked lists
3, Little knowledge of this topic
the merged linked list can be implemented recursively, which is easy to understand.
4, Instructions for group addition
I believe most of the people who read my article are "college students", and those who can go to college are "elites", so we naturally want to "keep improving". If you are still a "freshman", then it's great. You have a lot of time. Of course, you can choose to "brush drama". However, if you "learn algorithms well", you will naturally "not be in the same breath" three years later.
here, I sorted out the classification of "dozens of basic algorithms" and click to open:
if the link is blocked or there is a permission problem, you can talk to the author in private.
list of general problem sets:
in order to make it interesting and "take care of beginners", at present, only the simplest algorithm "enumeration series" (including linear enumeration, double pointer, prefix sum, bisection enumeration and trisection enumeration) is open. When half of the members have finished all the questions in the "enumeration series", the next chapter will be opened until all the questions are finished, If you are still in the group, you will become a member of the expert panel of "writing algorithms in the dead of night".
don't underestimate this expert group. In three years, you will be beyond the reach of others. If you want to join, you can contact me. Considering that everyone is a student and has no "main source of income", you "won't ask for anything" on your way to become God.
🔥 Contact the author, or scan the QR code of the author's home page and add a group to join the list of questions 🔥
C language free animation tutorial, punch in with me! 🌞 Daylight science C language 🌞
Entry level C language real topic summary 🧡 100 cases of introduction to C language 🧡
Several dynamic graphs learn a data structure 🌳 Drawing data structure 🌳
Group learning and group growth 🌌 Introduction to Algorithms 🌌
Gold Classic graphic course for competitors 💜 Writing algorithm in the dead of night 💜