Given the head of a doubly linked list, remove the first node and return the head of the resulting list.
Each node stores an integer val and two links: prev (the node before it) and next (the node after it). Deleting the head means the second node becomes the new head — and because it is now first, its prev link must point to nothing.
Return the new head. If the list becomes empty, return the empty list (a null head).
Input: head = [1, 2, 3] Output: 2 <-> 3 The first node 1 is removed, and node 2 becomes the new head with its prev pointing to nothing.
Input: head = [2, 5, 7, 8, 99, 100] Output: 5 <-> 7 <-> 8 <-> 99 <-> 100 The head node 2 is deleted, and the remaining list starts from node 5.
- 2 <= number of nodes <= 10^5 - 1 <= node.val <= 10^9
Deleting the head of a doubly linked list is the hello world of pointer surgery — but it hides one detail that trips beginners: the prev link. Get that right and the rest is a two-line change.
In plain words: the new head is the old head's next, and that new head's prev must be cleared to null. Formally, given head, return head.next after setting head.next.prev = null (and return null if the list had a single node).
Worked example — head = [1, 2, 3]
before: null <- 1 <-> 2 <-> 3 -> null
^head
delete the head (node 1):
new head = 1.next = node 2
node 2.prev = null <- the crucial step
after: null <- 2 <-> 3 -> null
^head
result: 2 <-> 3
Asking about boundaries before you code shows you are thinking about the shape of the data, not just the happy path.
“Can the list be empty when I am called?”
If a null head is possible, I must return null instead of dereferencing it.
“What if the list has exactly one node?”
Deleting it leaves an empty list, so the correct return is a null head, not a dangling node.
“How large can the list get?”
Up to 100000 nodes, so an O(n) rebuild is wasteful when an O(1) pointer fix exists.
Before I start, I have a couple of clarifying questions.
First, can the head be null when the function is called?
And if the list has a single node, I should return an empty list after deleting it — is that right?
Removing the front of a list does not disturb the ordering of anything behind it. The node at position two is already fully linked to the rest — it just needs to be promoted.
head -> 2 -> 3 -> ... becomes head -> 3 -> ... is WRONG (skips 2) head -> 1 -> 2 -> ... delete 1 head -> 2 -> ... correct
Because it is doubly linked, the second node still carries a prev pointer aimed at the deleted head. If you do not clear it, the new head lies about having a predecessor. Set newHead.prev = null.
You only ever touch two pointers — the returned head and its prev. A million-node list and a two-node list take the same work. Rebuilding the list would be O(n) for no benefit.
| Rebuild copy | Pointer surgery | |
|---|---|---|
| Idea | Walk from node 2, copy every value into a fresh list | Return head.next, clear its prev |
| Time | O(n) | O(1) |
| Space | O(n) | O(1) |
The full code for both lives in the Approaches selector below.
Key takeaway
To delete a node in a doubly linked list, rewire its neighbours' links — never rebuild. For the head, that means promoting head.next and setting its prev to null, in constant time.
if head is null or head.next is null: return null newHead = head.next newHead.prev = null return newHead