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

定义一个函数,在该函数中可以实现任意两个整数的加法。由于没有限定输入两个数的大小范围,我们也要把它当作大数问题来处理。

如果面试题是关于n位的整数并且没有限定n的取值范围,或者是输入任意大小的整数,那么这个题目很有可能是需要考虑大数问题的。字符串是一个简单、有效的表示大数的方法。

题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间(时间复杂度的计算方式???)删除该结点。

解题思路:在单向链表中删除一个结点,最常规的做法无疑是从链表的头结点开始,顺序遍历查找要删除的结点,并在链表中删除该结点。这种按顺序查找的思路其时间复杂度自然就是O(n).

 

注:(a)一个链表。(b)删除结点i之前,先从链表的头节点开始遍历到i前面的一个结点h,把h的m_pNext指向i的下一个结点j,再删除结点i。(c)把结点j的内容复制覆盖结点i,接下来再把结点i的m_pNext指向j的下一个结点之后删除结点j。这种方法不用遍历链表上结点i前面的结点。

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

值得注意的是,上午代码仍然不是完美的代码,因为它基于一个假设:要删除的结点的确在链表中。我们需要O(n)的时间才能判断链表中是否包含某一个结点。受到O(1)时间的限制,我们不得不把确保结点在链表中的责任推给了函数DeleteNode的调用者。在面试的时候,我们可以和面试官讨论这个假设,这样面试官就会觉得我们考虑问题非常全面。

当我们想删除一个结点时,并不一定要删除这个结点本身。可以把下一个结点的内容复制出来覆盖被删除结点的内容,然后把下一个结点删除。

猜你喜欢

转载自www.cnblogs.com/zhibei/p/9207390.html
今日推荐