题目描述
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点
示例 1:
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:
输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
思考
- 本题有两种方法去解决,分别是采用虚拟头结点和不采用虚拟头结点。
- 采用虚拟头结点的方式:不需要考虑考虑删除的节点是否是头结点。
- 不采用虚拟头结点的方式:需要分删除节点是头结点和不是头结点两种情况。
思路
这里以链表 1 4 2 4 来举例,移除元素4。
我们要操作的节点是目标节点的前一个节点和后一个节点.
不采用虚拟头结点(需要区分目标节点是否是头结点)
当目标节点是头结点时,进行head=head.next,即:
当目标节点不是头结点时,进行cur.next=cur.next.next,即:
设置虚拟头结点
这时,移除头结点便与移除其他节点操作一致了!
代码
虚拟头结点
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var deleteNode = function(head, val) {
var virtualNode=new ListNode("a"); //创建虚拟头结点
virtualNode.next=head;//将虚拟头结点变为链表的第一个节点
let cur=virtualNode; //指针指向链表第一个节点
//当cur.next 不为空时
while(cur.next!=null){
//判断下一个节点是否是目标节点
if(cur.next.val==val){
cur.next=cur.next.next; //删除目标节点
}else{
cur=cur.next; //否则移动指针
}
}
return virtualNode.next; //返回链表
};
不使用虚拟头结点
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var deleteNode = function(head, val) {
let cur=head;
while(cur!=null&&cur.next!=null){
//判断head节点是否是目标节点
if(cur.val==val){
head=head.next; //移动head节点
cur=head;
}else{
if(cur.next.val==val){
cur.next=cur.next.next; //操作目标节点的前一个节点和后一个节点。
}else{
cur=cur.next;
}
}
}
return head;
};
结果
总结
- 要知道操作的节点是目标节点的
前一个和后一个. - 不使用虚拟头结点时,需要区分目标节点是否是head节点的情况。