描述:给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
示例:
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
常规思路:定义一个暂时变量用来删除节点,注意若要删除a节点,则需使用a前一个节点来删除a,这种方法时间复杂度是o(n),因为最坏情况下要遍历整个链表才能找到待删除元素。空间复杂度是O(1),仅需要使用一个额外的节点temp
/**
* 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) {
if(head.val == val) return head.next
var temp = head
while(temp.next != null){
if(temp.next.val == val){
temp.next = temp.next.next
}else temp = temp.next
}
return head
};
leetcode版本与原题给出的ListNode不同,原版本ListNode定义
/**
* @param {ListNode} head
* @param {ListNode} toDelete
* @return {ListNode}
*/
var deleteNode = function(head, toDelete) {};
原书上的待删除节点是ListNode指针类型,可以思考O(1)时间复杂度的做法:
toDelete.val = toDelete.next.val
toDelete.next = toDelete.next.next
//可以直接删除toDelete节点(前提是toDelete节点不是最后一个节点)
如果toDelete是最后一个节点,那么就退化为常规解法,代码如下:
var head = function(toDelete, head){
if(!toDelete || !head) return null
if(toDelete.next != null) { //toDelete节点不是尾节点
toDelete.val = toDelete.next.val
toDelete.next = toDelete.next.next
return head
} else{
let temp = new ListNode()
temp.next = head
while(temp.next.next != null){
temp = temp.next
}
temp.next = null
return head
}
}
时间复杂度