{x}
blog image

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

 

Follow-up: Can you solve the problem in O(1) extra memory space?

Problem: Reverse Nodes in k-Group

Given a linked list's head and an integer k, 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, the left-out nodes at the end should remain as they are. You can only change the nodes themselves, not their values.

Approach: Iterative Reversal

The most efficient approach is an iterative solution that reverses groups of k nodes at a time. It avoids recursion's overhead.

  1. Dummy Node: Create a dummy node to simplify handling the head of the list. This node points to the actual head.

  2. Iteration: Iterate through the linked list using two pointers: pre (previous group's tail) and cur (current group's head).

  3. Group Extraction: For each iteration, cur moves k nodes forward. If cur becomes null before reaching k nodes, it means there are fewer than k nodes left, and the remaining list should not be reversed.

  4. Reversal: If k nodes are found, reverse the sublist starting at pre.next and ending at cur. A separate reverse helper function efficiently handles this.

  5. Connection: After reversal, connect the reversed sublist back to the main list by connecting pre to the new head of the reversed sublist and the tail of the reversed sublist to the next group's head (cur.next).

  6. Advance: Update pre to point to the tail of the reversed sublist, and continue the process.

Time and Space Complexity

  • Time Complexity: O(n), where n is the number of nodes in the linked list. Each node is visited and processed a constant number of times.
  • Space Complexity: O(1). The algorithm uses a constant amount of extra space regardless of the input size.

Code (Python)

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
 
class Solution:
    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        dummy = ListNode(next=head)  # Dummy node for easy head handling
        pre = dummy
 
        while True:
            count = 0
            cur = pre
            for i in range(k):
                cur = cur.next
                if not cur:  # Not enough nodes for a full group
                    return dummy.next
                count +=1
 
            #Reverse the next k nodes
            next_group = cur.next #store next group
            tail = pre.next
            for i in range(k):
                temp = tail.next
                tail.next = cur.next
                cur.next = tail
                tail = temp
            pre.next = cur
            pre = tail
 
 

Code (Java)

class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode dummy = new ListNode(0, head);
        ListNode pre = dummy;
 
        while (true) {
            ListNode cur = pre;
            int count = 0;
            for (int i = 0; i < k; i++) {
                cur = cur.next;
                if (cur == null) {
                    return dummy.next;
                }
                count++;
            }
 
            ListNode nextGroup = cur.next;
            ListNode tail = pre.next;
            for (int i = 0; i < k; i++) {
                ListNode temp = tail.next;
                tail.next = cur.next;
                cur.next = tail;
                tail = temp;
            }
 
            pre.next = cur;
            pre = tail;
        }
    }
}

(Similar code can be implemented in other languages like C++, JavaScript, Go, etc., following the same logic.)

This iterative approach provides a clear, concise, and efficient solution to the "Reverse Nodes in k-Group" problem. Remember to handle edge cases such as an empty list or k being greater than the list length.