在O(1)时间删除链表结点

题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点。


思路:

        在单向链表中删除一个结点,最常规的做法是从链表头结点开始,顺序遍历查找要删除的结点的前一个结点,然后把要删除的结点的next赋给要删除的结点的前一个结点的next即可完成。但是这种思路由于要顺序查找,时间复杂度为O(n)。

        那是否一定需要得到被删除的结点的前一个结点呢?当然不是!我们可以很方便的得到要删除的结点的下一个结点,所以我们只需要把要删除的结点的下一个结点的内容赋值给要删除的结点的内容,然后删除要删除的结点的下一个结点即可。

        注意:除了头指针和节点指针是null这种特殊输入之外(这种特殊输入是每个方法都必须考虑需要进行特殊处理的!),还有两种特殊情况,需要特殊考虑:

                    1.单链表只有一个结点,且要删除的结点就是这个结点,此时直接将头结点置为空即可,即head=null。

                    2.单链表有多个结点,但是,要删除的结点为尾节点,此时它没有下一个结点!所以我们只能从头结点开始顺序遍                  历得到该结点的头结点,并完成删除操作。


时间复杂度分析:

        对于n-1个非尾节点而言,我们可以在O(1)把下一个结点的内存复制覆盖要删除的结点,并删除下一个结点;对于尾节点而言,仍需顺序查找,时间复杂度为O(n)。所以平均复杂度为[(n-1)*O(1)+O(n)]/n,结果还是O(1),符合要求。


java实现:

public class DeleteNode {

	class ListNode{
		int data;
		ListNode next;
	}
	
	public void deleteNode(ListNode head, ListNode p){//p指向要删除的结点
		if(head==null||p==null)
			return;
		//只有一个结点的情况,且要删除的结点即为该节点
		if(head==p){
			head=null;
		}
		//有多个结点,且要删除的结点不是尾节点
		else if(p.next!=null){
			p.data=p.next.data;
			p.next=p.next.next;
		}
		//有多个结点,且要删除的是最后一个结点
		else{
			ListNode q = head;
			while(q.next!=p){
				q=q.next;
			}
			q.next=null;
			//q.next = p.next;
		}
	}
}
另外,值得注意的是,上述代码是基于一个假设:要删除的结点的确在链表中。我们需要O(N)的时间才能判断链表中是否包含某一结点,但是受到O(1)的限制,我们只能把确保结点在链表的责任推给deleteNode()方法的调用者,这点在面试的时候需要说明。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值