Skip to content

Instantly share code, notes, and snippets.

@optimistiks
Last active March 24, 2023 00:36
Show Gist options
  • Save optimistiks/a27cc8c42f68b9d6f9870841b6fe2252 to your computer and use it in GitHub Desktop.
Save optimistiks/a27cc8c42f68b9d6f9870841b6fe2252 to your computer and use it in GitHub Desktop.
Reverse nodes in even length groups
export function reverseEvenLengthGroups(head) {
if (!head.next) {
return head;
}
// we skip the first node since it's an odd group 1, and start with the second node and the second group
// this is the max number of nodes in a group we're currently iterating (can be less nodes if it's the last group)
let currentGroupLength = 2;
// this is the number of nodes we visited in the current group
let currentGroupNodesCount = 0;
// start node of the current group
let currentGroupStart = head.next;
// node that precedes the starting node of the current group
let currentGroupPrev = head;
let cursor = currentGroupStart;
while (cursor) {
currentGroupNodesCount += 1;
const isLastGroup = cursor.next === null;
// we should reverse the current group if
// it's the last group (curr.next = null) and we've seen an even number of nodes in the last group
// OR
// it's an even group (2, 4) and we've seen all the nodes of the group
const shouldReverseGroup =
(currentGroupLength % 2 === 0 &&
currentGroupNodesCount === currentGroupLength) ||
(isLastGroup && currentGroupNodesCount % 2 === 0);
if (shouldReverseGroup) {
reverseGroup(currentGroupPrev, currentGroupStart, currentGroupNodesCount);
// at this point, currentGroupStart is actually the end node of the reversed group
// reset values to prepare for the next group iteration
currentGroupPrev = currentGroupStart;
currentGroupStart = currentGroupStart.next;
currentGroupNodesCount = 0;
currentGroupLength += 1;
cursor = currentGroupStart;
} else {
cursor = cursor.next;
}
}
return head;
}
// reverse group of length nodes, starting from head,
// prev is the node that precedes the head node
function reverseGroup(prev, head, length) {
if (prev) {
prev.next = null;
}
let l = 0;
let newPrev = null;
let curr = head;
while (curr && l < length) {
const next = curr.next;
curr.next = newPrev;
newPrev = curr;
curr = next;
l += 1;
}
// at this point newPrev is the head of the reversed group
// and head is the end node of the reversed group
if (prev) {
// reconnect the reversed group with the preceding node of the group
prev.next = newPrev;
}
// reconnect the reversed group with the next node of the group
head.next = curr;
return newPrev;
}

Reverse all of the nodes that are present in the groups with an even number of nodes in them.
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... ) (1,2,3,4...).
The length of a group is the number of nodes assigned to it.

In other words:

  • 1st node forms the 1st group.
  • 2nd and 3rd nodes form the 2nd group.
  • Nodes 4, 5 and 6 for the 3rd group.

Return head of the resulting linked list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment