码迷,mamicode.com
首页 > 其他好文 > 详细

面试题18(一):在O(1)时间删除链表结点

时间:2018-08-09 22:05:25      阅读:94      评论:0      收藏:0      [点我收藏+]

标签:hit   直接   href   nod   turn   space   plist   font   打开   

// 面试题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(1)时间删除链表结点

标签:hit   直接   href   nod   turn   space   plist   font   打开   

原文地址:https://www.cnblogs.com/BoqianLiu/p/9451813.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!