题目描述
删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
【链表】
链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域,指针域存放的是指向下一个节点的指针,最后一个节点的指针域指向null。
链表如何删除结点?
只需要将第一个4节点的next指针,指向下一个6节点就可以了。
我们需要考虑一个特殊情况就是如果我们要移除的元素在头结点怎么办?
移除头结点和移除其他节点的操作是不一样的,因为链表中的其他节点都是通过前一个节点来移除当前节点的,而头结点没有前一个节点,那么头结点应该如何移除?
两种方式:
1)将头结点向后移动一位,这样就从链表中移除了一个头结点
2)设置一个虚拟的头结点,这样删除头结点就不需要在考虑了
方式一 删除头结点单独处理
这样头结点就被移除了。
class Solution {
public ListNode removeElements(ListNode head, int val) {
//删除值和目标值相同的头结点后,可能新的头结点也值相等,用循环解决
//如果节点是空并且及节点的值等于要删除的值,就把指针指向下一个结点
while(head!=null&&head.val==val){
head=head.next;
}
if(head==null) return head;
ListNode pre=head;用来删除和目标值相等的非头结点
//循环的条件是当前结点后还有结点
while(pre.next!=null){
if(pre.next.val==val){
pre.next=pre.next.next;//如果非头结点的值=要删除的值就把指针指向他的下下个
}else{
pre=pre.next;//如果下一个值不等于要删除的元素就指向他的下一个
}
}
return head;
}
}
第二种做法 设置虚拟头结点
设置一个虚拟的头结点然后让他指向链表中的第一个元素,这样如果头结点等于目标要删除的值的时候就不需要单独处理了。
【例题】
删除头结点1
虚拟头结点指向旧的头结点了。
还是之前的删除方式。
这样头结点1 就删除了,最后return 头结点的时候,是 return PreHead.next;这个才是新的头结点。
class Solution {
public ListNode removeElements(ListNode head, int val) {
//第二种做法设置虚拟的头结点
ListNode PreHead = new ListNode(0);//虚拟头结点
//虚拟头结点指向head,如果头结点=目标删除值的时候方便处理,不需要单独判断
PreHead.next = head;
/*设置这个指向虚拟头结点是作用是如果直接用PreHead操作的话会改变PreHead指针
最后return的时候就没法找到有效的头结点了。*/
ListNode pre = PreHead;
while(pre.next != null){
if(pre.next.val == val){
pre.next = pre.next.next;
}else{
pre = pre.next;
}
}
return PreHead.next;//返回的这个才是新的头结点
}
}
参考:
https://mp.weixin.qq.com/s?__biz=MzUxNjY5NTYxNA==&mid=2247484132&idx=1&sn=032d3d00bdfb7179941306a2aa50c9f1&scene=21#wechat_redirect