{x}
blog image

Reverse Nodes in Even Length Groups

You are given the head of a linked list.

The nodes in the linked list are sequentially assigned to non-empty groups whose lengths form the sequence of the natural numbers (1, 2, 3, 4, ...). The length of a group is the number of nodes assigned to it. In other words,

  • The 1st node is assigned to the first group.
  • The 2nd and the 3rd nodes are assigned to the second group.
  • The 4th, 5th, and 6th nodes are assigned to the third group, and so on.

Note that the length of the last group may be less than or equal to 1 + the length of the second to last group.

Reverse the nodes in each group with an even length, and return the head of the modified linked list.

 

Example 1:

Input: head = [5,2,6,3,9,1,7,3,8,4]
Output: [5,6,2,3,9,1,4,8,3,7]
Explanation:
- The length of the first group is 1, which is odd, hence no reversal occurs.
- The length of the second group is 2, which is even, hence the nodes are reversed.
- The length of the third group is 3, which is odd, hence no reversal occurs.
- The length of the last group is 4, which is even, hence the nodes are reversed.

Example 2:

Input: head = [1,1,0,6]
Output: [1,0,1,6]
Explanation:
- The length of the first group is 1. No reversal occurs.
- The length of the second group is 2. The nodes are reversed.
- The length of the last group is 1. No reversal occurs.

Example 3:

Input: head = [1,1,0,6,5]
Output: [1,0,1,5,6]
Explanation:
- The length of the first group is 1. No reversal occurs.
- The length of the second group is 2. The nodes are reversed.
- The length of the last group is 2. The nodes are reversed.

 

Constraints:

  • The number of nodes in the list is in the range [1, 105].
  • 0 <= Node.val <= 105

Problem Description

The problem asks to reverse nodes in even-length groups of a linked list. The groups are formed sequentially with lengths 1, 2, 3, 4, and so on. Only groups with even lengths need to be reversed.

Approach

The solution iterates through the linked list, identifying groups of nodes based on the sequence of natural numbers (1, 2, 3...). For each group, it checks if the length is even. If it is, the nodes within that group are reversed. This process continues until the end of the linked list is reached.

The solution employs a helper function reverse to efficiently reverse a portion of the linked list. This function takes the head of the sublist and the length of the sublist as input.

The main function calculates the total number of nodes in the linked list. It then iteratively processes groups of nodes, determining the appropriate length for each group and calling the reverse function when needed. Finally, it returns the modified head of the linked list.

Code Explanation (Python)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseEvenLengthGroups(self, head: Optional[ListNode]) -> Optional[ListNode]:
        def reverse(head, l): #Helper function to reverse a sublist of length l
            prev, cur, tail = None, head, head #Initialize pointers
            i = 0
            while cur and i < l: #Iterate through the sublist
                t = cur.next #Store the next node
                cur.next = prev #Reverse the link
                prev = cur #Move prev pointer
                cur = t #Move cur pointer
                i += 1
            tail.next = cur #Connect the reversed sublist to the rest
            return prev #Return the new head of the reversed sublist
 
 
        n = 0
        t = head
        while t: #Calculate the total number of nodes
            t = t.next
            n += 1
        dummy = ListNode(0, head) #Create a dummy node to simplify the process
        prev = dummy
        l = 1
        while (1 + l) * l // 2 <= n and prev: #Iterate through groups
            if l % 2 == 0: #Check if group length is even
                prev.next = reverse(prev.next, l) #Reverse the sublist if even
            i = 0
            while i < l and prev: #Move prev pointer to the end of the current group
                prev = prev.next
                i += 1
            l += 1 #Increment group length
        left = n - l * (l - 1) // 2 #Handle the last group
        if left > 0 and left % 2 == 0: #Reverse last group if it's even
            prev.next = reverse(prev.next, left)
        return dummy.next #Return the modified head
 

Explanation of Key Parts:

  • reverse(head, l): This function reverses a sublist of length l starting at head. It uses three pointers (prev, cur, tail) to efficiently reverse the links.
  • n = 0; t = head; while t:: This loop counts the total number of nodes in the linked list.
  • dummy = ListNode(0, head): A dummy node is added to simplify handling the beginning of the list.
  • while (1 + l) * l // 2 <= n and prev:: This loop iterates through the groups, using the formula for the sum of natural numbers to determine the group boundaries.
  • if l % 2 == 0:: Checks if the current group length is even.
  • left = n - l * (l - 1) // 2: Calculates the length of the last group.

Time and Space Complexity

Time Complexity: O(N), where N is the number of nodes in the linked list. The algorithm iterates through the list once to count nodes and then iterates again to process the groups. Reversing a sublist takes O(k) time where k is the length of the sublist, but the sum of k across all sublists is still O(N).

Space Complexity: O(1). The algorithm uses a constant amount of extra space to store pointers and variables. The reverse function uses a constant number of extra pointers as well.

Code in Other Languages

The logic remains largely the same across different languages. The main differences are in syntax and data structure representation. Refer to the code provided in the original response for Java and TypeScript implementations. These implementations follow the same algorithmic approach.