25. Reverse Nodes in k-Group
Given the head of a linked list, reverse the nodes of the list k at a time, and return the modified list.
k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes, in the end, should remain as it is.
You may not alter the values in the list’s nodes, only nodes themselves may be changed.
Example 1:
Input: head = [1,2,3,4,5], k = 2
Output: [2,1,4,3,5]
Example 2:
Input: head = [1,2,3,4,5], k = 3
Output: [3,2,1,4,5]
Constraints:
- The number of nodes in the list is n.
- 1 <= k <= n <= 5000
- 0 <= Node.val <= 1000
From: LeetCode
Link: 25. Reverse Nodes in k-Group
Solution:
Ideas:
Key Functions:
-
reverse(struct ListNode* start, struct ListNode* end): This is a helper function that reverses a sublist of a linked list from the node start up to but not including the node end.
-
reverseKGroup(struct ListNode* head, int k): This is the main function that reverses nodes in k-group chunks in a given linked list.
Key Steps:
-
Counting Nodes: The function first counts the total number of nodes in the linked list.
-
Initialization: Several pointers are initialized to keep track of various parts of the list. These include pointers for the end of the previous group (prev_group_end), the start and end of the current group (group_start and group_end), and a new head for the list (new_head).
-
Main Loop: The main while loop runs as long as there are at least k nodes left in the list to reverse.
- Inside the loop, group_end is moved to point to the k-th node from group_start.
- A null check is performed to break out of the loop if group_end is NULL.
- The nodes between group_start and group_end are then reversed using the reverse function.
- The reversed group is connected to the previous group or set as the new head of the list.
- Pointers are updated to move to the next group of nodes.
-
Connecting Leftover Nodes: After all possible groups of k nodes have been reversed, any remaining nodes (fewer than k) are connected to the last reversed group.
-
Return: Finally, the function returns the new head of the linked list.
Code:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverse(struct ListNode* start, struct ListNode* end) {
struct ListNode* prev = NULL;
struct ListNode* curr = start;
struct ListNode* next;
while (curr != end) {
if (curr == NULL) {
break;
}
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
int count = 0;
struct ListNode* tmp = head;
while (tmp) {
count++;
tmp = tmp->next;
}
struct ListNode* prev_group_end = NULL;
struct ListNode* new_head = NULL;
struct ListNode* group_start = head;
struct ListNode* group_end = head;
while (count >= k) {
for (int i = 1; i < k; i++) {
if (group_end) {
group_end = group_end->next;
}
}
if (!group_end) {
break;
}
struct ListNode* next_group_start = group_end->next;
group_end->next = NULL;
struct ListNode* reversed_group = reverse(group_start, next_group_start);
if (prev_group_end) {
prev_group_end->next = reversed_group;
}
if (!new_head) {
new_head = reversed_group;
}
prev_group_end = group_start;
group_start = next_group_start;
group_end = next_group_start;
count -= k;
}
if (prev_group_end) {
prev_group_end->next = group_start;
}
return new_head ? new_head : head;
}