【剑指Offer】面试题13:在O(1)时间删除链表结点

一:题目描述

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


二:解题思路

最常规的做法:从链表的头指针开始顺序遍历链表,找到要删除的指针,并在链表中删除该指针。时间复杂度O(n)

我们为什么要遍历链表呢?因为我们想找到要删除结点 i 的前一个结点 j ,删除 i 的操作 : 

pj->next=pi->next  ;

delete pi;

pi=NULL  //防止野指针的问题

因为单链表只有next指针,所以要遍历。


那么一定要知道要删除结点的前一个结点么?--答案当然是否定的,要不然这个题怎么做呢!

解决方法:

将要删除结点的下一个结点内容复制需要删除的结点上覆盖原始的内容,再把下一个结点删除,那不就相当于删除的指定结点。


需要考虑的问题:

1.删除结点有下一个结点

----按照上面的思路进行

2.删除结点没有下一个结点,是尾结点

---这个时候就需要从头遍历链表找到要删除的结点的前一个节点

3.链表中只有一个结点,删除的结点既是头结点也是尾结点

---删除该结点,将头指针置NULL

4.链表为空,或要删除的结点为空

--函数开始时,加入判断

5.要删除的结点不在链表中(如果要解决这个问题,需要遍历一遍链表,不符合时间要求,我们默认要删除的结点在链表中这个假设)


时间复杂度:[(n-1)*O(1)+1*O(n)]/n=O(1)


三:代码实现

ListNode* deleteNode(ListNode* head, ListNode* pDelete){
	if (head == NULL || pDelete == NULL)
		return NULL;

	//要删除的结点的下一个结点不为空
	if (pDelete->next != NULL){
		ListNode* pNode = pDelete->next;
		//将下一个结点的信息赋值给pDelte
		pDelete->val = pNode->val;
		pDelete->next = pNode->next;

		//删除下一个结点
		delete pNode;
		pNode = NULL; //防止野指针的情况
	}//if
	else if (head == pDelete){
		//如果链表只包含一个结点,要删除的是头结点
		delete pDelete;
		pDelete = NULL;

		cout << "只有一个结点,删除头指针" << endl;
		//头指针置NULL
		head = NULL;
	}
	else{
		//删除尾指针
		//遍历链表
		ListNode* pNode = head;
		//找到要删除结点的前一个结点
		while (pNode->next != pDelete){
			pNode = pNode->next;
		}

		pNode->next = NULL;
		delete pDelete;
		pDelete = NULL;
	}

	return head;
}//deleteNode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值