Losing head/tail while rewiring
Wrong move: Pointer updates overwrite references before they are saved.
Usually fails on: List becomes disconnected mid-operation.
Fix: Store next pointers first and use a dummy head for safer joins.
Move from brute-force thinking to an efficient approach using linked list strategy.
You are given the head of a linked list. Delete the middle node, and return the head of the modified linked list.
The middle node of a linked list of size n is the ⌊n / 2⌋th node from the start using 0-based indexing, where ⌊x⌋ denotes the largest integer less than or equal to x.
n = 1, 2, 3, 4, and 5, the middle nodes are 0, 1, 1, 2, and 2, respectively.Example 1:
Input: head = [1,3,4,7,1,2,6] Output: [1,3,4,1,2,6] Explanation: The above figure represents the given linked list. The indices of the nodes are written below. Since n = 7, node 3 with value 7 is the middle node, which is marked in red. We return the new list after removing this node.
Example 2:
Input: head = [1,2,3,4] Output: [1,2,4] Explanation: The above figure represents the given linked list. For n = 4, node 2 with value 3 is the middle node, which is marked in red.
Example 3:
Input: head = [2,1] Output: [2] Explanation: The above figure represents the given linked list. For n = 2, node 1 with value 1 is the middle node, which is marked in red. Node 0 with value 2 is the only node remaining after removing node 1.
Constraints:
[1, 105].1 <= Node.val <= 105Problem summary: You are given the head of a linked list. Delete the middle node, and return the head of the modified linked list. The middle node of a linked list of size n is the ⌊n / 2⌋th node from the start using 0-based indexing, where ⌊x⌋ denotes the largest integer less than or equal to x. For n = 1, 2, 3, 4, and 5, the middle nodes are 0, 1, 1, 2, and 2, respectively.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Linked List · Two Pointers
[1,3,4,7,1,2,6]
[1,2,3,4]
[2,1]
remove-nth-node-from-end-of-list)reorder-list)remove-linked-list-elements)middle-of-the-linked-list)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2095: Delete the Middle Node of a Linked List
/**
* Definition for singly-linked list.
* public 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 deleteMiddle(ListNode head) {
ListNode dummy = new ListNode(0, head);
ListNode slow = dummy, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
slow.next = slow.next.next;
return dummy.next;
}
}
// Accepted solution for LeetCode #2095: Delete the Middle Node of a Linked List
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func deleteMiddle(head *ListNode) *ListNode {
dummy := &ListNode{Val: 0, Next: head}
slow, fast := dummy, dummy.Next
for fast != nil && fast.Next != nil {
slow, fast = slow.Next, fast.Next.Next
}
slow.Next = slow.Next.Next
return dummy.Next
}
# Accepted solution for LeetCode #2095: Delete the Middle Node of a Linked List
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def deleteMiddle(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode(next=head)
slow, fast = dummy, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
slow.next = slow.next.next
return dummy.next
// Accepted solution for LeetCode #2095: Delete the Middle Node of a Linked List
/**
* [2095] Delete the Middle Node of a Linked List
*
* You are given the head of a linked list. Delete the middle node, and return the head of the modified linked list.
* The middle node of a linked list of size n is the ⌊n / 2⌋^th node from the start using 0-based indexing, where ⌊x⌋ denotes the largest integer less than or equal to x.
*
* For n = 1, 2, 3, 4, and 5, the middle nodes are 0, 1, 1, 2, and 2, respectively.
*
*
* Example 1:
* <img alt="" src="https://assets.leetcode.com/uploads/2021/11/16/eg1drawio.png" style="width: 500px; height: 77px;" />
* Input: head = [1,3,4,7,1,2,6]
* Output: [1,3,4,1,2,6]
* Explanation:
* The above figure represents the given linked list. The indices of the nodes are written below.
* Since n = 7, node 3 with value 7 is the middle node, which is marked in red.
* We return the new list after removing this node.
*
* Example 2:
* <img alt="" src="https://assets.leetcode.com/uploads/2021/11/16/eg2drawio.png" style="width: 250px; height: 43px;" />
* Input: head = [1,2,3,4]
* Output: [1,2,4]
* Explanation:
* The above figure represents the given linked list.
* For n = 4, node 2 with value 3 is the middle node, which is marked in red.
*
* Example 3:
* <img alt="" src="https://assets.leetcode.com/uploads/2021/11/16/eg3drawio.png" style="width: 150px; height: 58px;" />
* Input: head = [2,1]
* Output: [2]
* Explanation:
* The above figure represents the given linked list.
* For n = 2, node 1 with value 1 is the middle node, which is marked in red.
* Node 0 with value 2 is the only node remaining after removing node 1.
*
* Constraints:
*
* The number of nodes in the list is in the range [1, 10^5].
* 1 <= Node.val <= 10^5
*
*/
pub struct Solution {}
use crate::util::linked_list::{ListNode, to_list};
// problem: https://leetcode.com/problems/delete-the-middle-node-of-a-linked-list/
// discuss: https://leetcode.com/problems/delete-the-middle-node-of-a-linked-list/discuss/?currentPage=1&orderBy=most_votes&query=
// submission codes start here
// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Clone, Debug)]
// pub struct ListNode {
// pub val: i32,
// pub next: Option<Box<ListNode>>
// }
//
// impl ListNode {
// #[inline]
// fn new(val: i32) -> Self {
// ListNode {
// next: None,
// val
// }
// }
// }
impl Solution {
pub fn delete_middle(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
Some(Box::new(ListNode::new(0)))
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore]
fn test_2095_example_1() {
let head = linked![1, 3, 4, 1, 2, 6];
let result = linked![1, 3, 4, 1, 2, 6];
assert_eq!(Solution::delete_middle(head), result);
}
#[test]
#[ignore]
fn test_2095_example_2() {
let head = linked![1, 2, 3, 4];
let result = linked![1, 2, 4];
assert_eq!(Solution::delete_middle(head), result);
}
#[test]
#[ignore]
fn test_2095_example_3() {
let head = linked![2, 1];
let result = linked![2];
assert_eq!(Solution::delete_middle(head), result);
}
}
// Accepted solution for LeetCode #2095: Delete the Middle Node of a Linked List
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function deleteMiddle(head: ListNode | null): ListNode | null {
const dummy = new ListNode(0, head);
let [slow, fast] = [dummy, head];
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
slow.next = slow.next.next;
return dummy.next;
}
Use this to step through a reusable interview workflow for this problem.
Copy all n nodes into an array (O(n) time and space), then use array indexing for random access. Operations like reversal or middle-finding become trivial with indices, but the O(n) extra space defeats the purpose of using a linked list.
Most linked list operations traverse the list once (O(n)) and re-wire pointers in-place (O(1) extra space). The brute force often copies nodes to an array to enable random access, costing O(n) space. In-place pointer manipulation eliminates that.
Review these before coding to avoid predictable interview regressions.
Wrong move: Pointer updates overwrite references before they are saved.
Usually fails on: List becomes disconnected mid-operation.
Fix: Store next pointers first and use a dummy head for safer joins.
Wrong move: Advancing both pointers shrinks the search space too aggressively and skips candidates.
Usually fails on: A valid pair can be skipped when only one side should move.
Fix: Move exactly one pointer per decision branch based on invariant.