题目:删除链表中等于给定值 val 的所有节点
1.介绍链表:
链表由一系列节点组成,每个节点包含两部分:
1.数据域:存储数据元素的值
2.指针域:指向链表中下一个节点的指针,指针允许我们遍历链表,由一个节点移动到下一个节点。
如下图所示:
2.解题思路一:在原链表上进行操作
首先链表里面没有现成的删除某一个元素的方法,但是每一个节点有指针域,用来指向下一个节点,那如何来删除目标节点呢,我们会想到,让目标节点的前一个节点直接指向目标节点的下一个节点,目标节点就间接的被删除了,如下图所示:
这样中间的节点直接就移除了,那么还会有一个问题,如果目标节点等于头节点(第一个节点)该怎么删除,因为链表的头节点叫head,我们可以让head = head.next (头节点=头节点的下一个节点)通过改变头节点的方式来间接删除头节点。
3.代码如下:
class Solution {
public ListNode removeElements(ListNode head,int val){
while (head != null && head.val == val) {//如果头节点不为空,并且头节点的值=目标值的话(head.val 头节点的值)
head = head.next;//头节点=头节点的下一个节点
}
ListNode cur = head;//定义一个指针,用来遍历链表,指向头节点,用来删除cur.next(cur的下一个节点),如果直接让cur指向cur.next,就无法找到cur.next的上一个节点,无法进行删除。
while (cur != null && cur.next!= null) {//如果指针和指针的下一个指针都不为空的话
if (cur.next.val == val) {//指针的下一个值= 目标值的话
cur.next = cur.next.next;//指针目前指向的节点变为指针指向的节点的下一个节点
}else {
cur = cur.next;//否则,就继续遍历当前链表
}
}
return head;//返回头指针
}
}
这样我们就可以做出来这道题,但是这种删除目标元素的方法并不统一,可能稍许复杂,我们可不可以优化上述方法使得操作链表的方法统一呢,大家可以看看下面的思路:
4.解题思路二:设置一个虚拟头节点
我们可以在头节点前面再设一个节点,指向头节点,这样头节点前面也有一个节点了,就可以对链表进行同一操作了。
代码如下:
class Solution {
public ListNode removeElements(ListNode head,int val){
ListNode dummy = new ListNode();//实例化一个虚拟头指针
dummy.next = head;//让这个虚拟头指针指向头节点
ListNode cur = dummy;//定义一个指针来遍历链表
while(cur.next != null) {
if (cur.next.val == val) {
cur.next = cur.next.next;
}else {
cur = cur.next;
}
}
return dummy.next;//返回的一定要是虚拟头指针指向的下一个节点,因为为头节点有可能被删除了
}
}
以上就是移除元素链表的两种解法,第二种有点难想,大家可以记住,这些都是链表的常用操作,大家还有什么疑问或者更好的方法,欢迎评论区留言或者私信!