面试题18:在O时间删除链表结点

Posted boqianliu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试题18:在O时间删除链表结点相关的知识,希望对你有一定的参考价值。

// 面试题18(一):在O(1)时间删除链表结点
// 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该
// 结点。链表结点与函数的定义如下:
// struct ListNode{
// int m_nValue;
// ListNode* m_pNext;
// };
// void deleteNode(ListNode** pListHead,ListNode* pToBeDeleted);

解题思路:

这是目前为止,唯一一道,我不看书就知道怎么做的题。

正常从头遍历的话,很明显时间复杂度是O(n),但是他把目标结点给出来了,这就好办了。

直接用目标节点下一个的m_nValue覆盖目标结点,然后删除目标结点就好了。

打开书一看,啊哈哈哈,果然是这个思路啊,就是作者考虑的比我周到多了。

首先,如果目标节点不是尾结点,直接用下一个节点覆盖目标节点,然后删除下一个结点

   如果目标节点就是尾结点(也是头结点),删除头结点。

   如果目标节点就是尾结点(不是头结点,链表有多个结点),那么只能从头结点开始遍历了。

然后分析一下时间复杂度,一个有n个结点的链表,非尾结点有n-1个,直接删除后边的结点,时间复杂度为(n-1)*O(1)。

尾节点有一个,时间复杂度为1*O(n),平均一下就是O(1),满足题目的要求。

c/c++:

void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted) {
	//参数校验
	if (pListHead == nullptr || pToBeDeleted == nullptr)
		return;

	//目标结点不位于尾结点,用下一个节点覆盖目标结点
	if (pToBeDeleted->m_pNext != nullptr) {
		ListNode* pNode = pToBeDeleted->m_pNext;
		pToBeDeleted->m_nValue = pNode->m_nValue;
		pToBeDeleted->m_pNext = pNode->m_pNext;

		delete pNode;
		pNode = nullptr;
	}
	//目标节点与头结点重合,链表只有一个结点
	else if (*pListHead == pToBeDeleted) {
		delete pToBeDeleted;
		pToBeDeleted = nullptr;
		*pListHead = nullptr;
	}
	//链表有多个节点,且目标结点是尾节点
	else {
		ListNode* pNode = *pListHead;
		while (pNode->m_pNext != pToBeDeleted) {
			pNode = pNode->m_pNext;
		}

		pNode->m_pNext = nullptr;
		delete pToBeDeleted;
		pToBeDeleted = nullptr;
	}

	return;
}

参考资料:

剑指offer第二版面试题18(一)

以上是关于面试题18:在O时间删除链表结点的主要内容,如果未能解决你的问题,请参考以下文章

《剑指offer》第十八题:在O时间删除链表结点

剑指Offer对答如流系列 - 在O时间删除链表结点

剑指Offer-代码的完整性面试题18.2:删除链表中的重复节点

剑指offer——面试题18.1:删除链表中重复的节点

剑指offer 面试18题

面试题18:删除链表节点