203. 移除链表元素
203. 移除链表元素
分析
移除头节点跟移除非头节点的操作不一样,很容易就想到,我们可以加一个虚拟头节点,然后统一移除操作。最后返回的时候,只返回虚拟节点的下一个节点即可,代码写出来非常优雅。
我们在编写代码移除链表中一个节点,是一定要记录这个节点的前一个节点的,同时也需要记录当前节点(可以省略掉),如果是双向链表,那节点内部已经有指针帮我们记录了,如果是单向的链表,则需要我们自己记录。在 while 循环中,我们需要根据定义,来更新前一个节点和当前节点。抓住定义,写代码就不会乱。
解题
public ListNode removeElements(ListNode head, int val) {
// 我们为dummyNode填充的值跟我们要删除的值绝不可能相等
ListNode dummyNode = new ListNode(-1,head);
ListNode preNode = dummyNode;
ListNode nowNode = dummyNode.next;
while(nowNode!=null){
if(nowNode.val==val){
// 此时 preNode 不变
preNode.next = nowNode.next;
nowNode=nowNode.next;
}else{
// 此时 preNode 要更新
preNode = nowNode;
nowNode=nowNode.next;
}
}
return dummyNode.next;
}
还有一个精简版的,只记录前一个结点即可,因为当前节点就是前一个结点通过 next 指针可以访问到,因此当前节点这个变量确实可以省略。
直接想到这个写法有点难。
public ListNode removeElements(ListNode head, int val) {
// 我们为dummyNode填充的值跟我们要删除的值绝不可能相等
ListNode dummyNode = new ListNode(-1,head);
ListNode preNode = dummyNode;
while(preNode.next!=null){
ListNode nowNode = preNode.next;
if(nowNode.val==val){
// 此时 preNode 不变
preNode.next = nowNode.next;
}else{
// 此时 preNode 要更新
preNode = nowNode;
}
}
return dummyNode.next;
}