问题描述
删除链表中等于给定值val
的所有节点。
示例:
输入: head = [1, 2, 6, 3, 4, 5, 6], val = 6
输出: head = [1, 2, 3, 4, 5]
题干信息提取:
- 删除指定值节点;
- 链表没有保证排序
- 原地操作,不能打乱链表其余节点相对位置
问题分析
这个题目难度为“简单”,所以比较容易有简单的思路:我们知道需要对每个节点进行值比较,之后相同的值删除即可。
这个时候会有两个具体操作需要梳理清晰:
- 删除操作是在确定值比较且相等之后进行的;
- 删除操作涉及到被删除节点的 前置节点以及后置节点,所以这里需要将注意力放在这个“前置节点
curr
”,来判断其后节点curr.next
的值与val
的关系;删除操作涉及到其再后节点curr.next.next
; - 边界条件的考虑,这里我们通过文章 算法修炼之路——【链表】Leetcode82 删除重复节点 II来判断出这里需要引入哨兵机制来统一 头节点符合删除时的动作规则。
步骤罗列
- 初始化哨兵节点
dummyHead
与游历指针curr
; - 遍历链表并判断
curr.next
的值与val
是否相等,相等则删除;否则更新curr = curr.next
并继续2; - 循环终止条件为
curr.next = null
,终止后返回dummyHead.next
.
解题代码
public static ListNode solutionWithP(ListNode head, int val) {
if (head == null || head.next == null) {
return head;
}
//1. init pointers and dummyHead
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode currP = dummyHead;
// 2. check node with val
while (currP.next != null) {
if (currP.next.val == val) {
currP.next = currP.next.next;
} else {
currP = currP.next;
}
}
return dummyHead.next;
}
复杂度分析
时间复杂度:这里我们对链表仅进行了一次遍历,故时间复杂度为O(n);
空间复杂度:我们没有初始化或设置额外的辅助容器,所以这里空间复杂度为O(1);
GitHub代码
完整的可运行文件参见GitHub。