203.移除链表元素
题意:
删除链表中等于给定值 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 输出:[]
思路:首先确定需要多少个额外的指针才能进行删除操作。肯定要有一个cur指针不断进行节点遍历判断节点的val值是否与目标值相同,其次考虑当要删除的节点是第一个节点时的情况,此时直接进行head = head->next操作即可,如果时这样的话我们需要额外判断要删除的节点是否为第一个节点,因为正常来说如果要删除的节点在中间的话,执行的操作应该是cur->next = cur->next->next(将待删除节点的下一个节点的地址赋值给指向待删除节点的指针),两种操作不一样,为了统一,我们可以再设置一个虚拟节点指向头指针head,使得head也变成一个中间节点,能够进行统一处理。
解法:javascript
var removeElements = function(head, val) {
const dHead = new ListNode(0, head);
let cur = dHead;
while(cur.next) {
if(cur.next.val === val) {
cur.next = cur.next.next;
continue;
}
cur = cur.next;
}
dHeadurn dHead.next;
};
代码执行示意图:现在假设val = 6
-
当删除的节点在第一个:
-
当删除的节点在中间:
提问:
1. let cur =dHead这个操作做了什么事?
首先要理解dHead是什么,dHead是一个指向了一个ListNode类型的节点(虚拟头节点)的指针,dHead里面存放的是这个节点的地址。将dHead的值赋给cur,此时cur也指向了这个虚拟头节点,拥有了能够从头开始操作该链表的能力。dHead存在的意义是为了保存该链表的初始地址,而cur是为了能够遍历链表进行删除节点的操作。
2. while(cur.next)中为什么判断的是cur.next?可不可以直接判断cur?
不可以。cur一开始就是指向虚拟节点的,而我们要判断的是从虚拟节点后开始的真正的节点,从cur->next开始才是真正的节点。
3. 为什么最后返回的是dHead.next而不是head?
看示意图中的第一种情况,head指针会因为删除了真正的头结点而丢失,所以应该借助dHead->next 来获取链表真正的初始位置。