题目
请编写一个函数,用于 删除单链表中某个特定节点 。在设计函数时需要注意,你无法访问链表的头节点 head ,只能直接访问 要被删除的节点 。题目数据保证需要删除的节点 不是末尾节点 。
示例1:
输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:指定链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9
示例2:
输入:head = [4,5,1,9], node = 1
输出:[4,5,9]
解释:指定链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9
代码
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next=node.next.next;
}
题目解析
对的,你没有看错,代码就是这么少,真不是为了水博客,本来是不为了这一道题目专门写这篇博客的,但是主要这道题目很有趣,我们先来看看解题思路。
当初次看到这道题目时,我也一头雾水,这题目到底说的是什么?不怕被笑话,就这么几个字我硬是读了两三分钟都没懂其中的意思,无奈之下我看了评论,这才懂了其中的意思。原来我们删除的都是val值对应的节点,但是这次是直接给你节点,让你将节点删除,原来我们是遍历整个链表寻找对应的val值再删除节点,但是这题目因为直接给你了删除的节点,因此我们不需要遍历链表了。我一开始的思路是想让删除的节点的前驱指向删除节点的后继,这样就可以完成了删除的操作,但问题就出在这里,我们无法找到删除节点的前驱,因此这个方法不可行,那么如何解决呢?这就引出了上面代码的解决方法。假设有这样一个链表:
假设我们要删除node,那么我们可以将node的val值变成后继的val值,也就是将5改成1,然后再将node的next指向node后继的后继也就是node的next赋值为0x456,像这样:
也就是说完成这道题,真正删除的不并不是node节点,而是把node节点变成自己的后继,再把自己的后继删除,完成这道题。看起来似乎很简单,但是能想到是真的不容易。在LeetCode中也评论中也有一个评论让人背后发凉:如何让自己在这个世界上消失,但是又不死?就是将自己变成另一个人,在将另一个人杀死。细想这道题确实是这样的。
好了这道题的解题思路就是这样了,如果有不同的看法或者思路,欢迎评论私信,谢谢各位的点赞。最后附上这题的链接。
附:LeetCode237题——删除链表中的节点