题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点。
由于给定的是单向链表,正常删除链表的时间复杂度是查找链表的时间复杂度即O(n),如果要求在O(1)时间复杂度内删除节点,通过遍历链表找到该节点的上一节点和下一节点的方法是行不通了。所以实现的思路是,根据给定的要删除的节点,可以直接找到其后年的节点,把后面的节点的内容复制到当前节点处,同时将当前节点指向其后面节点的后面节点保证链表不断开,再把下一节点删掉就相当于把给定的节点删除了。
需要考虑到的一点是,如果要删除的节点是链表的尾节点的话,那还是需要从头结点按照顺序遍历到尾节点的前一节点,然后删除尾节点,总的平均时间复杂度就是[(n-1)*1+O(n)]/n,结果还是O(1)。
class ListNode{
int val;
ListNode next = null;
public ListNode(int val){
this.val = val;
}
}
public class DeleteNode {
public static void deleteNode(ListNode head,ListNode node){
if (head == null || node ==null){
return;
}
//要删除的节点不是尾节点,把后一个结点的值赋值给该节点,并把该节点纸箱后一个节点的后一个节点
if (node.next!=null){
node.val = node.next.val;
node.next = node.next.next;
}
//如果链表只有一个节点,删除头结点也是删除尾节点
else if (head == node){
head = null;
}
//链表中有多个节点,删除尾节点
else{
ListNode pHead = head;
while (pHead.next!=node){
pHead = pHead.next;
}
pHead.next = null;
}
}
}