链表删除操作
leetcode链接:leetcode.cn/problems/re…
画图不容易出错,删除链表元素:
这道题可以有两种解法:使用虚拟节点和不使用虚拟节点(今天只用了虚拟节点的方法,不使用的方法也可以了解下)
不使用虚拟节点
从上面的图看出,如果要删除元素的话,需要知道上一个节点的指针。
但头节点没有上一个节点,所以头节点需要特殊处理。
使用while遍历,使得链表中的头节点一定不等于val。
while (head && head.val === val) {
head = head.next;
}
然后从头节点开始,遍历元素进行删除操作。
为什么需要一个临时指针等于head指针?
如果用head指针遍历元素,等遍历结束的时候,head指针已经指向链表的末尾了,无法返回新的头节点。使用临时指针遍历元素,最后直接返回head指针。
let cur = head;
while (cur && cur.next) {
if (cur.next.val === val) {
cur.next = cur.next.next;
} else {
cur = cur.next;
}
}
使用虚拟节点
为什么需要虚拟头节点?
一般的节点在删除的时候,直接把前一个节点的next指向后一个节点即可。但是头节点没有前一个节点,可以在头节点前加一个虚拟头节点,就不需要特殊处理头节点了。
let dummy = new ListNode(0, head);
为什么需要一个临时指针等于dummy指针?
理由同上,不过要注意和不使用虚拟头节点时的区别。一个等于head指针,一个等于dummy指针。因为不使用虚拟头节点的方法,已经特殊处理过头节点了,但虚拟头节点还没有处理过。
使用虚拟头节点的方法,head指针一直没有变化过,一直都是原来链表。返回的时候不能返回head,而应该是dummy.next。
var removeElements = function(head, val) {
// 使用虚拟头节点
let dummy = new ListNode(0, head);
// 要理解为什么cur要等于dummy而不是head
let cur = dummy;
// 要获取cur.next的val值,所以cur.next不能为空
while (cur.next) {
if (cur.next.val === val) {
cur.next = cur.next.next;
} else {
cur = cur.next;
}
}
return dummy.next;
};
设计链表
leetcode链接:leetcode.cn/problems/de…
考察链表综合操作的题目
明天补博客