Swapping Adjacent Nodes in Linked List
This algorithm swaps every two adjacent nodes in a linked list using a dummy head approach for consistent handling.
Key implementation details:
- Use a dummy head node to simplify edge cases
- Maintain current pointer before the pair being swapped
- Careful manage temporary references during swapping
- Ensure loop condition checks prevent null pointer exceptions
function ListNode(val, next) {
this.val = (val === undefined ? 0 : val);
this.next = (next === undefined ? null : next);
}
function swapAdjacentNodes(listHead) {
const dummy = new ListNode(0, listHead);
let current = dummy;
while (current.next && current.next.next) {
const firstNode = current.next;
const thirdNode = current.next.next.next;
current.next = current.next.next;
current.next.next = firstNode;
firstNode.next = thirdNode;
current = current.next.next;
}
return dummy.next;
}
Removing Nth Node From End of List
Length Calculation Approach
This method calculates total length first, then finds the target position for removal.
function removeFromEnd(head, positionFromEnd) {
const dummy = new ListNode(0, head);
let current = head;
let nodeCount = 0;
while (current) {
nodeCount++;
current = current.next;
}
let previousIndex = nodeCount - positionFromEnd - 1;
let previousNode = dummy;
while (previousIndex-- >= 0) {
previousNode = previousNode.next;
}
previousNode.next = previousNode.next.next;
return dummy.next;
}
Two Pointer Technique
Using fast and slow pointers where fast pointer moves ahead by n positions first.
function removeFromEndTwoPointer(head, positionFromEnd) {
const dummy = new ListNode(0, head);
let fast = dummy;
let slow = dummy;
for (let i = 0; i <= positionFromEnd; i++) {
fast = fast.next;
}
while (fast) {
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return dummy.next;
}
Finding Intersection Node of Two Linked Lists
This algorithm finds the intersection point by aligning the starting positions of both lists.
function getListSize(head) {
let count = 0;
let current = head;
while (current) {
count++;
current = current.next;
}
return count;
}
function findIntersectionNode(headA, headB) {
let currentA = headA;
let currentB = headB;
let sizeA = getListSize(headA);
let sizeB = getListSize(headB);
if (sizeA < sizeB) {
[currentA, currentB] = [currentB, currentA];
[sizeA, sizeB] = [sizeB, sizeA];
}
let difference = sizeA - sizeB;
while (difference-- > 0) {
currentA = currentA.next;
}
while (currentA && currentA !== currentB) {
currentA = currentA.next;
currentB = currentB.next;
}
return currentA;
}
Detecting Cycle Starting Point in Linked List
Using Floyd's cycle detection algorithm to find the starting node of a cycle.
function detectCycleStart(head) {
if (!head || !head.next) return null;
let fast = head;
let slow = head;
while (fast && fast.next) {
fast = fast.next.next;
slow = slow.next;
if (fast === slow) {
let pointer1 = fast;
let pointer2 = head;
while (pointer1 !== pointer2) {
pointer1 = pointer1.next;
pointer2 = pointer2.next;
}
return pointer1;
}
}
return null;
}