题目描述
删除链表中等于给定值val
的所有节点。
示例1:
输入: head = [1, 2, 6, 3, 4, 5, 6], val = 6
输出: [1, 2, 3, 4, 5]
思路分析
这道题目为简单程度,所以我们这里给出简单思路。
我们需要考虑一般规则,当删除节点为中间或非两端节点时,直接令被删节点的前置节点指针直接指向被删节点后置节点即可,这里我们可将核心代码给出:
代码1: 删除节点的一般实现
// assume that "nodePrev -> node -> nodeNext":
// nodePrev.next = node;
// (node.val == val) = True
// remove node
nodePrev.next = node.next; // OR nodePrev.next = nodePrev.next.next;
边界情况考虑
这里需要考虑两个边界情况:
- 当链表头节点满足
head.val == val
时; - 当链表尾节点满足
tail.val == val
时。
问题1:头节点满足删除条件
这里我们由代码1可知,我们的操作依据主要是nodePrev
节点,但是头节点没有前置节点,这时候我们可以主动引入哨兵节点dummyHead
,直接令dummyHead.next = head
, 则一般规则就对**问题1 **依然适用。
问题2:尾节点满足删除条件
我们先通过代码1进行简单的分析,当尾节点要被删除时,其后置节点为null
, 此时将前置节点指向空指针nodePrev.next = null
; 并不影响代码,所以这里我们直接给出步骤及解题代码:
解题步骤
- 初始化指针,一个为遍历指针
p
, 另一个为哨兵节点dummyHead
; - 遍历原始链表,并删除指定节点;
- 返回结果
dummyHead.next
.
解题代码
public static ListNode solution(ListNode head, int val) {
if (head == null) {
return null;
}
/* Step1: Init. pointers */
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode p = dummyHead;
/* Step2: go through the head-list
and
remove specified nodes with value of "val"
*/
while(p.next != null){
if(p.next.val == val){
p.next = p.next.next;
}else{
p = p.next;
}
}
/* Step3: return dummyHead's next-node */
return dummyHead.next;
}
复杂度分析
时间复杂度:我们对原始链表进行了一次遍历,容易理解时间复杂度为O(N)
;
空间复杂度:我们这里没有设置辅助容器,故空间复杂度为O(1)
.
GitHub源码
完整可运行文件请访问GitHub。