Stats
Neetcode
| Easy | 3 |
| Medium | 8 |
| Hard | 3 |
Structy 15 questions / 24 points points into two parts (17 + 7)
Part 1 (17 = 10 basics + 7 questions)
- 3 starters: welcome, intro, warm up
- 4 warm-up questions: values, sum, find, get by index
- ⭐classic - reverse list
- Iterative - O(n) time, o(1) space

- recursive - O(n) space and time

- Iterative - O(n) time, o(1) space
- ⭐2 classics - zipper lists & merge sorted list
- Zipper : O(min(n1,n2)) time, O(1) space =just few vars
- Lengths might be diff. always start from list 1
- assign tail.next not tail in loops
- 4 pointers & a
counter- current1, current2, head & current/tail .next (new list)
- Recursion:

- Merge sorted list
- Similar to above - but not sure abt the new head
- Dummy node needed as head might change
- return dummy.next!
- Iterative

- Recursion

- Zipper : O(min(n1,n2)) time, O(1) space =just few vars
- pep talk
- 2 easy traversal problems - is universal (unique value linked list) & longest streak
-
is universal

-
longest streak

-
- ⭐2 classics - head can change problems - remove node, insert node
- remove node (only once) - corner scenarios
- visual

- if head == target :Head might change but no need of dummy node
- simply return head.next
- iterative:
breakis important for only first deletion case
- recursion

- visual
- Insert Node : head can change
- visual

- index = 0 ⇒ new node becomes head.
- visual
- remove node (only once) - corner scenarios
- 2 closers - quiz and wrap up
Part 2 (7 advanced questions)
- ⭐palindrome - O(n) space and time with a tricky O(n) time + O(1) space
- Iterative linear solution

- O(1) solution
- Use a fast and slow pointer to find the middle.
- Reverse the second half in-place.
- Compare both halves.
const linkedPalindrome = (head) => { if (!head || !head.next) return true; // Step 1: Find middle (slow will point to middle) let slow = head, fast = head; while (fast && fast.next) { slow = slow.next; fast = fast.next.next; } // Step 2: Reverse second half let prev = null; while (slow) { let nextNode = slow.next; slow.next = prev; prev = slow; slow = nextNode; } // Step 3: Compare first half and reversed second half let left = head, right = prev; while (right) { if (left.val !== right.val) return false; left = left.next; right = right.next; } return true; };
- Iterative linear solution
- ⭐middle value- fast & slow
- handles odd and even length conditions well out of box
- in case of even length - it returns the second-mid node

- ⭐classic - cycle
- using Set - O(n) space

- using fast and slow - O(1) space

- using Set - O(n) space
- ⭐un-dupe sorted linked list - very good “head may change” prob
- Dummy node pattern - below code creates a new linked list

- A better in-place version - O(1) space

- Dummy node pattern - below code creates a new linked list
- create linked list - try the recursive o(n) solution
- simple O(n) dummy node problem
- Iterative

- Recursive
-using slice - O(N^2)
- pass index - O(n)

- pass index - O(n)
- build a queue : classic problem - n = number of items currently on the Queue - Total Queue Space: O(n) - enqueue - Time: O(1) - Space: O(1) - dequeue - Time: O(1) - Space: O(1)
class Node {
constructor(val) {
this.val = val;
this.next = null;
}
}
class Queue {
constructor() {
this.head = null;
this.tail = null;
this.size = 0;
}
enqueue(val) {
if (this.size === 0) {
this.head = new Node(val);
this.tail = this.head;
} else {
this.tail.next = new Node(val);
this.tail = this.tail.next;
}
this.size += 1;
}
dequeue() {
if (this.size === 0) {
return null;
}
const value = this.head.val;
if (this.size === 1) {
this.head = null;
this.tail = null;
} else {
this.head = this.head.next;
}
this.size -= 1;
return value;
}
}
- ⭐classic add lists - watch video - https://structy.net/problems/premium/add-lists
- lots of corner scenarios
- same length
- diff length - missing digits as zero
- handling carry “45 + 46 = 91”
- handling final carry “45 + 56 = 101”
- output is longer than each of list
- o(max(n1, n2)) time and space - we have to parse the longer list completely.
- iterative:
- recursive
- lots of corner scenarios
Problem Checklist
- Are we changing head? dummy head needed?
- what we are retruning? Do we need to preserve the head?
Generic Things
- Insertion - O(1) vs Array’s o(n)
- Just head is enough to pass on linked list
- Traversing iterative vs recursive

More patterns
Reversing half of linked list:
-
Use
fast = head.nextif you wantslowto land before midpoint (e.g., to reverse second half). -
Use
fast = headif you wantslowto land at or after midpoint (e.g., to reverse first half).
| Goal | Where slow should land | Correct fast init |
|---|---|---|
| Reverse second half | Just after midpoint | fast = head.next |
| Reverse first half | At or after midpoint | fast = head |
| Reorder with middle skip | Just before midpoint | fast = head.next |
Reversing second half of linked list - slow and fast start differently
function reverseSecondHalf(head) {
if (!head || !head.next) return head;
// Step 1: Find the middle of the list
let slow = head, fast = head.next;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
// Step 2: Reverse the second half from 'slow'
let prev = null, curr = slow;
while (curr) [curr.next, prev, curr] = [prev, curr, curr.next];
// Step 3: Attach the reversed second half back to the first half
let mid = head;
while (mid.next !== slow && mid.next) mid = mid.next;
mid.next = prev;
return head;
}
- so 1 → 2 → 3 → 4 → 5
- Step 1 - find the mid node (slow) as node 3
- Step 2 - second half becomes like 5 → 4 → 3 where prev is at 5, and slow at 3 → null
- right now,
2.nextis still pointing to3, and3.nextis nownulldue to reversal. 
- right now,
- Step 3 - start again from beginning and come till “2” or where mid.next = slow
- once there, reconnect 2.next to 5 or mid.next = prev

Reverse the first half - here fast and slow start together
function reverseFirstHalf(head) {
if (!head || !head.next) return head;
// Step 1: Find the middle of the list
let slow = head, fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
// Step 2: Reverse the first half from 'head' just befor slow
let prev = null, curr = head;
let tail = head; //preserve the head
while (curr != slow) [curr.next, prev, curr] = [prev, curr, curr.next];
// Step 3: Attach the reversed first half back to the slow
tail.next = slow;
return prev;
}
- Original list: 1 → 2 → 3 → 4 → 5
- After reversing first half: 2 → 1 → 3 → 4 → 5