题目描述:
给你一个链表的头节点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 <= k <= 50
情况分析: 1)该链表中只有一个head节点,此时直接返回输出"[ ]" 2)要删除的节点在中间,且它的下一个不是目标删除的元素(直接将prev的next指向其下一个元素的next域) 3)要删除的节点在中间,且它的下一个也是需要删除的(此时将不能就直接更改,因为可能会出现它的下一个还是的情况) 综合2)3)点,此时设置两个指针,prev和del,当找到第一个目标时,让del先向下继续扫描看是不是要删除的元素,①是,继续向下判断 ②不是,就让prev.next = del.next; 4)再分析一下如果是最后一个元素,是否被以上两种情况包含,根据以上情况,能够将最后一个元素删除,不需要考虑 5)再分析第一个如果为要删除的元素,发现:第一个元素删不掉,需要处理这个head,①将它放在最后进行删除,先从第二个开始 ②先从头节点开始向后删,直到第一个出现不为目标节点的节点,让它成为新的头节点 ③在头节点之前建立一个虚拟头节点,使之可以从头来进行删除,最后返回这个节点。 6)返回 ListNode类型
情况一:
情况二:
情况三:
/**
* 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) {
//判断头节点本身是否存在
if (head == null) {
System.out.println("该链表没有任何节点");
return null;
}
//设置指针,向后扫描
ListNode prev = head;
while (prev.next != null) {
if(prev.next.val == val) {
prev.next = prev.next.next;
}else {
prev = prev.next;
}
}
//最后处理头节点
if(head.val == val) {
head = head.next;
}
return head;
}
}
其他思路:
第一种:先处理头节点
class Solution {
public ListNode removeElements(ListNode head, int val) {
//删除目标头结点后,可能新的头结点的值也相等,用循环来判断,知道出现第一个不等于val的新的头节点
while(head!=null&&head.val==val){
head=head.next;
}
if(head==null) {
return head;
}
ListNode prev=head;
//确保当前结点后还有结点
while(prev.next!=null){
if(prev.next.val==val){
prev.next=prev.next.next;
}else{
prev=prev.next;
}
}
return head;
}
}
第二种:虚拟头节点
class Solution {
public ListNode removeElements(ListNode head, int val) {
//创建一个虚拟头结点
ListNode dummyNode=new ListNode(val-1);
dummyNode.next=head;
ListNode prev=dummyNode;
//确保当前结点后还有结点
while(prev.next!=null){
if(prev.next.val==val){
prev.next=prev.next.next;
}else{
prev=prev.next;
}
}
return dummyNode.next;
}
}