1.描述
给定一个单链表中的一个等待被删除的节点(非表头或表尾)。请在在O(1)时间复杂度删除该链表节点。
样例
给定 1->2->3->4,和节点 3,删除 3 之后,链表应该变为 1->2->4。
2.分析
按照一般的思路,删除一个节点node首先需要找到他所在的位置,让node的上一个节点直接指向node的下一个节点,
空过node,也就是让node->perior的next指向node->next,但这样做首先需要知道node->perior(这在单链表中不好实现),
并且这样做是o(n)的算法,题目要求为o(1)时间复杂度。在上面的分析中,我们发现只要让node的下一个节点取代node的位置
就相当于空过了node让node的前一个节点指向后一个节点,因此有了最简单的一句代码*node=*(node->next);
3.代码:
/**
* Definition of ListNode
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param node: a node in the list should be deleted
* @return: nothing
*/
void deleteNode(ListNode *node) {
// write your code here
*node=*(node->next);
}
};
4.总结
下面两种情况分别对应了两种错误。把红字部分替换为下面的绿字部分。
(1)
node->val=node->next->val;
node=node->next;
乍一看似乎没有什么区别,所存数据val给了,指针也给了,但事实上这段代码运行是wrong answer
因为从根本上看,只是把node的下一个节点所存数据赋值给了node节点,同时让node指针指向下一个节点,
故此没有达到删除node节点的目的。
(2)
node=node->next;
node->val=node->next->val;
这两句和上面两句看起来也有些相似,只是变了变位置,但如果运行出来结果就不是wrong answer
而是run time error了。
因此我们发现要删除某个节点最重要的还是找到他所在的地址,*node才是真正对现在node所在的空间
进行操作。
本文介绍了一种在O(1)时间复杂度内删除单链表中指定节点的方法,通过让待删节点复制其下一节点的数据并跳过下一节点来实现高效删除。

1674

被折叠的 条评论
为什么被折叠?



