剑指offer--13.在O(1)时间删除链表结点

题目:给定单向链表的头指针和一个结点指针,定义一个函数在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;
		}
	}

}

猜你喜欢

转载自blog.csdn.net/autumn03/article/details/80169506