题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点。
由于给定的是单向链表,正常删除链表的时间复杂度是查找链表的时间复杂度即O(n),如果要求在O(1)时间复杂度内删除节点,通过遍历链表找到该节点的上一节点和下一节点的方法是行不通了。所以实现的思路是,根据给定的要删除的节点,可以直接找到其后年的节点,把后面的节点的内容复制到当前节点处,同时将当前节点指向其后面节点的后面节点保证链表不断开,再把下一节点删掉就相当于把给定的节点删除了。
需要考虑到的一点是,如果要删除的节点是链表的尾节点的话,那还是需要从头结点按照顺序遍历到尾节点的前一节点,然后删除尾节点,总的平均时间复杂度就是[(n-1)*1+O(n)]/n,结果还是O(1)。
1 /** 2 * 剑指offer面试题13:在O(1)时间删除链表节点 3 * 题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点。 4 * @author GL 5 * 6 */ 7 public class No13DeleteNodeInList { 8 9 public static class ListNode{ 10 public int data; 11 public ListNode next; 12 public ListNode(int data,ListNode next){ 13 this.data=data; 14 this.next=next; 15 } 16 } 17 18 public static void deleteNode(ListNode head,ListNode node){ 19 //删除尾节点,采用顺序查找找到尾节点的前一节点 20 if(node.next==null){ 21 while(head.next!=node){ 22 head=head.next; 23 } 24 head.next=null; 25 } 26 //要删除的节点是头结点 27 else if(head==node){ 28 head=null; 29 } 30 //要删除的节点是中间普通节点 31 else{ 32 node.data=node.next.data; 33 node.next=node.next.next; 34 } 35 } 36 public static void main(String[] args) { 37 ListNode tail=new ListNode(1,null); 38 ListNode c=new ListNode(2,tail); 39 ListNode b=new ListNode(3,c); 40 ListNode head=new ListNode(4,b); 41 deleteNode( head,c); 42 while(head!=null){ 43 System.out.println(head.data); 44 head=head.next; 45 } 46 47 } 48 }