难度:easy
基础的链表删除元素,如果是C++,要记得手动清理移除的节点;
三种方法:不用虚拟头结点,用虚拟头结点的方法,递归方法;
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) {
// if(head == null) {
// return head;
// }
//如果head.val==val,后移head
while (head != null && head.val == val) {
head = head.next;
}
//检查头结点是否为空
if(head == null) {
return head;
}
ListNode pre = head;
ListNode cur = head.next;
//remove
while (head != null && cur != null) {
if (cur.val == val) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return head;
}
}
复杂度分析
-
时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表一次。
-
空间复杂度:O(1)。
注意:这一步非常重要,检查头结点是否为空的步骤要 在删除完符合head.val==val的头结点后(有可能整个链表均被删除),在给pre,cur赋值之前(若整个链表被删完,head是空指针)。
//检查头结点是否为空
if(head == null) {
return head;
}
用虚拟头结点的方法:
class Solution {
public ListNode removeElements(ListNode head, int val) {
//head是否为空
if (head == null) {
return head;
}
ListNode dummy = new ListNode(-1, head); //虚拟头结点,dummy.next = head
ListNode pre = dummy;
ListNode cur = dummy.next;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
}
复杂度分析:
同上