# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
// Definition for singly-linked list.
// struct ListNode {
// int val;
// ListNode *next;
// ListNode(int x) : val(x), next(nullptr) {}
// };
class Solution {
public:
void deleteNode(ListNode* node) {
node->val = node->next->val;
node->next = node->next->next;
}
};
// Definition for singly-linked list.
// public class ListNode {
// int val;
// ListNode next;
// ListNode(int x) { val = x; }
// }
class Solution {
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
}
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} node
* @return {void} Do not return anything, modify node in-place instead.
*/
var deleteNode = function(node) {
node.val = node.next.val;
node.next = node.next.next;
};
You are given the head of a singly linked list, and a node
that is not the tail node in this list. Your task is to delete the given node
from the linked list. However, you are not given access to the head of the list — only to the node
to be deleted.
node.next
is not null).
At first glance, deleting a node from a singly linked list usually requires knowing the previous node, so you can update its next
pointer to skip the node being deleted. However, in this problem, we are not given access to the head or any previous nodes — only to the node that needs to be deleted.
This restriction forces us to think differently. Since we can't access the previous node, we can't change its next
pointer. But, since the node to be deleted is not the last node, we can access its next
node. Instead of removing the current node, what if we overwrite its value with the value of the next node, and then remove the next node instead? This way, the effect is as if we deleted the current node.
The solution leverages the fact that we can access the node to be deleted and its next node. Here's how we achieve the deletion:
By doing this, the current node now contains the data of the next node, and the next node is gone from the list. The linked list behaves as if the original node was deleted.
Let's walk through an example. Suppose the linked list is:
4 -> 5 -> 1 -> 9
You are given the node with value 5
(not the head), and you need to delete it.
4 -> 5 -> 1 -> 9
.
5.next
(which is 1
) into 5
. Now the list is 4 -> 1 -> 1 -> 9
.
5.next
(now holding value 1
) to point to 5.next.next
(which is 9
). The list is now 4 -> 1 -> 9
.
5
is now gone, and the list is as if 5
was deleted.
This is optimal for this problem, since we are only modifying the given node and its neighbor.
In summary, the key insight is to recognize that in a singly linked list, if you can't access the previous node, you can still "delete" a node by copying the next node's value and skipping over it. This approach is both time and space efficient, requiring only two simple operations. The elegance of the solution comes from its simplicity and the clever use of in-place modifications.