Nodes are instances of the provided ListNode class. Write reverse_blocks(head, k) that cuts the list into consecutive blocks of k nodes, starting from the head, reverses the order of the nodes inside each full block, and returns the new head. If the last block has fewer than k nodes, it stays exactly as it is.
Rearrange the original nodes by re-pointing next fields: don't create nodes and don't change any val. An empty list is None.
In the examples, lists are written as Python lists, head first:
reverse_blocks([1, 2, 3, 4, 5, 6, 7, 8], 3) # [3, 2, 1, 6, 5, 4, 7, 8]
reverse_blocks([1, 2, 3, 4, 5, 6], 2) # [2, 1, 4, 3, 6, 5]
reverse_blocks([1, 2, 3], 3) # [3, 2, 1]
reverse_blocks([1, 2, 3], 4) # [1, 2, 3]
reverse_blocks([1, 2, 3], 1) # [1, 2, 3]
Constraints: up to 200,000 nodes; 1 <= k <= 200,000. Aim for O(n) time and O(1) extra memory: the tests measure peak memory, so don't collect the nodes into a Python list, and don't recurse.
Show hint
Before touching a block, look ahead k nodes to confirm it is complete. Reversing a block is the familiar whole-list reversal with a fixed number of steps; the fiddly part is remembering the node just before the block and the block's old first node, which becomes its new tail.