https://leetcode.com/problems/reverse-nodes-in-k-group/submissions/1221405161/?envType=study-plan-v2&envId=top-interview-150
def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
if not head: return head
def reverse(node, k):
prev, curr = None, head
while k:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
k -= 1
return prev
ptr = head
ktail = None
new_head = None
while ptr:
count = 0
ptr = head
# find the head of the start of the next k nodes
# so ptr will move forward until it points to the
# first node that is not part of the current k nodes
while count < k and ptr:
ptr = ptr.next
count += 1
if count == k:
# returns the starting node of the current k nodes
# that were just reveresed, this is the node that was
# originally right behind where ptr is right now
rev_head = reverse(head, k)
# if this is the first set of k nodes we are reversing
# we need to make sure we store its "head" aka it's new
# starting node as the overall starting point of our linked
# list, since this is the node we have to return
if not new_head:
new_head = rev_head
# if we already reversed a group of k nodes there will be
# a ktail, which we need to attach to the starting node
# of the new group of k nodes we just reversed
if ktail:
ktail.next = rev_head
# k tail stores the last node of the current k nodes that
# was reversed. It will attach to the next set of nodes.
# we set ktail to head because before reversing, head used to be
# the starting point of the current k nodes, but after reversing
# it becomes the last node of the current k nodes
ktail = head
# move the head to the starting node of the next k nodes
head = ptr
# if there is a ktail, attach it to head which stores the start of
# next group of nodes
if ktail:
ktail.next = head
return new_head if new_head else head
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
// Reverse k nodes of the given linked list.
ListNode* reverseLinkedList(ListNode* head, int k) {
// This function assumes that the list contains at least k nodes.
ListNode* new_head = nullptr;
ListNode* ptr = head;
while (k > 0) {
// Keep track of the next node to process in the original list
ListNode* next_node = ptr->next;
// Insert the node pointed to by "ptr" at the beginning of the reversed list
ptr->next = new_head;
new_head = ptr;
// Move on to the next node
ptr = next_node;
// Decrement the count of nodes to be reversed by 1
k--;
}
// Return the head of the reversed list
return new_head;
}
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* ptr = head;
ListNode* ktail = nullptr;
// Head of the final, modified linked list
ListNode* new_head = nullptr;
// Keep going until there are nodes in the list
while (ptr != nullptr) {
int count = 0;
// Start counting nodes from the head
ptr = head;
// Find the head of the next k nodes
while (count < k && ptr != nullptr) {
ptr = ptr->next;
count += 1;
}
// If we counted k nodes, reverse them
if (count == k) {
// Reverse k nodes and get the new head
ListNode* revHead = reverseLinkedList(head, k);
// new_head is the head of the final linked list
if (new_head == nullptr)
new_head = revHead;
// ktail is the tail of the previous block of reversed k nodes
if (ktail != nullptr)
ktail->next = revHead;
ktail = head;
head = ptr;
}
}
// Attach the final, possibly un-reversed portion
if (ktail != nullptr)
ktail->next = head;
return new_head == nullptr ? head : new_head;
}
};