题目描述
删除链表中等于给定值 val 的所有节点。
示例:
输入:1->2->6->3->4->5->6, val = 6
输出:1->2->3->4->5
思路分析
「使用双指针」
为了方便处理,可以利用哑节点记录表头节点。使用双指针 pre 和 cur 分别指向上一个节点和当前节点。
如果当前节点为需要被删除的目标节点,那么上一个节点的指针就要指向当前节点的下一个节点。
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode node = new ListNode(0);
node.next = head;
ListNode pre = node;
ListNode cur = head;
while (cur != null) {
if (cur.val == val) {
cur = cur.next;
pre.next = cur;
} else {
cur = cur.next;
pre = pre.next;
}
}
return node.next;
}
}
稍微优化了一下:
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode node = new ListNode(0);
node.next = head;
ListNode pre = node;
ListNode cur = head;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return node.next;
}
}
「进一步简化」
前面使用 pre 和 cur 两个指针,可以进一步简化,只使用一个 cur 指向当前节点,由于只有一个节点,因此必须提前发现需要删除的目标节点。
如果当前节点的下一个节点为需要被删除的节点,当前节点指向下一个节点的下一个节点。
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode node = new ListNode(0);
node.next = head;
ListNode cur = node;
while (cur != null && cur.next != null) {
if (cur.next.val == val) {
cur.next = cur.next.next;
} else {
cur = cur.next;
}
}
return node.next;
}
}