来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-linked-list-elements
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例 2:输入:head = [], val = 1
输出:[]
示例 3:输入:head = [7,7,7,7], val = 7
输出:[]
提示:
列表中的节点数目在范围 [0, 104] 内
1 <= Node.val <= 50
0 <= val <= 50
参考文章:听说用虚拟头节点会方便很多?
思路:
这个题目考验的是链表的删除操作,主要需要考虑的点在于当头节点需要进行删除时应该怎么做。这里用到了虚拟头节点,即new一个新的链表节点作为虚拟头节点,然后将原链表的头节点赋给虚拟头节点的next节点,这样子,原链表的头节点就变成了新链表的第二个节点,就可以将原链表的头节点与其他链表中的结点一样一视同仁进行判断与删除操作,最后再返回虚拟头节点的next节点作为输出即可。
在写本题的时候犯了两个错误。
1、需要注意while循环的判断语句应该是判断rnNode.next(rnNode代表当前节点)是否为空指针,如果为空指针则跳出循环。这里while循环的判断语句不应该写判断rnNode是否为空指针。
2、注意,判断是否需要删除节点是通过rnNode.next的值进行判断的,因此这个时候应该已经确认rnNode是不需要进行删除的。当rnNode.next.val是要删除的值时,进行删除操作,rnNode.next = rnNode.next.next,之后,不应该进行rnNode = rnNode.next的赋值操作,因为这个时候新的rnNode.next是否需要删除还未判断,只有当rnNode.next.val不是要删除的值时,才能进行rnNode = rnNode.next的操作,因为这个时候已经确认rnNode.next不需要进行删除了。
本题Java代码:
/**
* 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 removeElements(ListNode head, int val) {
ListNode ansNode = new ListNode(0, head);
ListNode rnNode = ansNode;
while(rnNode.next!=null){
if(rnNode.next.val==val){
rnNode.next=rnNode.next.next;
}else{
rnNode=rnNode.next;
}
}
return ansNode.next;
}
}