首页
外语
计算机
考研
公务员
职业资格
财经
工程
司法
医学
专升本
自考
实用职业技能
登录
计算机
给定链表的头指针和一个结点指针,在O(1)时间删除该结点。链表结点的定义如下: struct ListNode { int m_nKey; ListNode* m_pNext; }; 函数的声明如下: void DeleteNode(L
给定链表的头指针和一个结点指针,在O(1)时间删除该结点。链表结点的定义如下: struct ListNode { int m_nKey; ListNode* m_pNext; }; 函数的声明如下: void DeleteNode(L
admin
2019-03-29
102
问题
给定链表的头指针和一个结点指针,在O(1)时间删除该结点。链表结点的定义如下:
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
};
函数的声明如下:
void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted);
选项
答案
/////////////////////////////////////////////////////////////////////// // Delete a node in a list // Input: pListHead - the head of list // pToBeDeleted - the node to be deleted /////////////////////////////////////////////////////////////////////// void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted) { if(!pListHead || !pToBeDeleted) return; // if pToBeDeleted is not the last node in the list if(pToBeDeleted->m_pNext != NULL) { // copy data from the node next to pToBeDeleted ListNode* pNext = pToBeDeleted->m_pNext; pToBeDeleted->m_nKey = pNext->m_nKey; pToBeDeleted->m_pNext = pNext->m_pNext; // delete the node next to the pToBeDeleted delete pNext; pNext = NULL; } // if pToBeDeleted is the last node in the list else { // get the node prior to pToBeDeleted ListNode* pNode = pListHead; while(pNode->m_pNext != pToBeDeleted) { pNode = pNode->m_pNext; } // deleted pToBeDeleted pNode->m_pNext = NULL; delete pToBeDeleted; pToBeDeleted = NULL; } } 值得注意的是,为了让代码看起来简洁一些,上面的代码基于两个假设:(1)给定的结点的确在链表中;(2)给定的要删除的结点不是链表的头结点。不考虑第一个假设对代码的鲁棒性是有影响的。至于第二个假设,当整个列表只有一个结点时,代码会有问题。但这个假设不算很过分,因为在有些链表的实现中,会创建一个虚拟的链表头,并不是一个实际的链表结点。这样要删除的结点就不可能是链表的头结点了。当然,在面试中,我们可以把这些假设和面试官交流。这样,面试官还是会觉得我们考虑问题很周到的。
解析
这是一道广为流传的Google面试题,能有效考察我们的编程基本功,还能考察我们的反应速度,更重要的是,还能考察我们对时间复杂度的理解。
在链表中删除一个结点,最常规的做法是从链表的头结点开始,顺序查找要删除的结点,找到之后再删除。由于需要顺序查找,时间复杂度自然就是O(n) 了。
我们之所以需要从头结点开始查找要删除的结点,是因为我们需要得到要删除的结点的前面一个结点。我们试着换一种思路。我们可以从给定的结点得到它的下一个结点。这个时候我们实际删除的是它的下一个结点,由于我们已经得到实际删除的结点的前面一个结点,因此完全是可以实现的。当然,在删除之前,我们需要需要把给定的结点的下一个结点的数据拷贝到给定的结点中。此时,时间复杂度为O(1)。
上面的思路还有一个问题:如果删除的结点位于链表的尾部,没有下一个结点,怎么办?我们仍然从链表的头结点开始,顺便遍历得到给定结点的前序结点,并完成删除操作。这个时候时间复杂度是O(n)。
那题目要求我们需要在O(1)时间完成删除操作,我们的算法是不是不符合要求?实际上,假设链表总共有n个结点,我们的算法在n-1总情况下时间复杂度是O(1),只有当给定的结点处于链表末尾的时候,时间复杂度为O(n)。那么平均时间复杂度[(n-1)*O(1)+O(n)]/n,仍然为O(1)。
转载请注明原文地址:https://www.kaotiyun.com/show/wRmZ777K
0
程序员面试
相关试题推荐
Arogueloosecalledahackercouldtakecontroloftheentiresystembyimplantinghisowninstructionsinthesoftwareandthe
WhenIseeclients,thisisthequestionthatI’maskedthemost.Ifyou’reinapublicplace,lookaround.【F1】Nearlyeveryone
[A]Theperson-skillsmatchapproachtoselection[B]Theimpactsofbadselectiondecisions[C]Theimportanceofstructu
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。
大整数数相乘的问题。
如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,则字符串一称之为字符串二的子串。注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中。请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。例如:输入两个
删除字符串中的数字并压缩字符串(神州数码以前笔试题),如字符串”abc123de4fg56”处理后变为”abcdefg”。注意空间和效率。(下面的算法只需要一次遍历,不需要开辟新空间,时间复杂度为O(N))
为邮件到达后应用规则“若发件人包含‘mary@sina.com’转发到wangtao@sina.com”。
软件设计模块化的目的是()。
随机试题
A.迟缓期B.对数期C.稳定期D.衰亡期E.任何时期细菌变异多发生在()
与经济高速发展相伴随的生态环境恶化的表现有()
女性,64岁,拟行局麻下手部脓肿切开引流术,注射麻醉药后不久出现面色潮红、恶心、视物模糊、血压上升和烦躁不安等表现,首先应考虑其出现了()。
不属于喜炎平注射液不良反应的是
费用效益分析,又称(),是环境影响的经济评价中使用的另一个重要的经济评价方法。
将目标项目资产所产生的独立的、可识别的未来收益作为抵押,通过信用增级计划在资本市场上发行具有固定收益率的高信用等级债券,这种融资方式称为()。
知识产权的权利主体依法享有独占使用智力成果的权利,他人不得侵犯,这体现了知识产权的()。
汇总记账凭证账务处理程序的优点之一是编制汇总记账程序的程序比较简单。()
自然灾害给人类带来磨难,同时又促使人类更加自觉地去认识和把握自然规律、增强抵御自然灾害的能力,进而推动人类文明进步。正如恩格斯所说,“没有哪一次巨大的历史灾难,不是以历史的进步为补偿的”。从灾难到进步,其中体现的深刻哲理是()。①“灾难”和“进步”作为矛
工程建设合同纠纷的仲裁由(51)的仲裁委员会仲裁。仲裁委员会做出裁决以后,当事人应当履行。当一方当事人不履行仲裁裁决时,另一方当事人可以依照民事诉讼法的有关规定向(52)申请执行。(51)
最新回复
(
0
)