题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点
思路:
1.最常规做法是从链表的头结点开始,顺序遍历查找要删除的结点,并在链表中删除该结点,时间复杂度为O(n)。
2.要删除结点i,先把i的下一个结点j内容复制到i,然后把i的指针指向结点j的下一个结点,此时再删除结点j。对于n-1个非尾结点,可以O(1)时间把下一个结点内容复制覆盖要删除的结点,然后删除下一个结点;对于尾结点,仍然要顺序查找,时间复杂度为O(n),因此平均为[(n-1)*O(1)+O(n)]/n,结果还是O(1)
注意:假设要删除的结点在链表中是存在的
public class wr13deleteNode { // 方法一,顺序查找 public boolean deleteNode(ListNode head,int index){ if(index<1||index>length(head)){ return false; } if(index==1){ head=head.next; return true; } int i=2; ListNode preNode=head; ListNode curNode=preNode.next; while(curNode!=null){ if(i==index){ preNode.next=curNode.next; return true; } preNode=curNode; curNode=curNode.next; i++; } return true; } // 方法二,复制覆盖 public int length(ListNode head){ int length=0; ListNode temp=head; while(temp!=null){ length++; temp=temp.next; } return length; } public void delete(ListNode head,ListNode deleteNode){ if(head==null || deleteNode==null){ return ; } if(deleteNode.next!=null){//待删除结点不是尾结点 ListNode temp=deleteNode.next; deleteNode.val=temp.val; deleteNode.next=temp.next; temp=null; } else if(head==deleteNode){//链表只有一个结点 deleteNode=null; head=null; } else{//待删除结点是尾结点,遍历 ListNode curNode=head; while(curNode.next!=deleteNode){ curNode=curNode.next; } curNode.next=null; deleteNode=null; } } }