33.在O(1)时间删除链表结点[DeleteListNode]
【题目】
给定链表的头指针和一个结点指针,在O(1)时间删除该结点。链表结点的定义如下:
|
1
2 3 4 5 6 |
struct ListNode
{ int m_nKey; ListNode *m_pNext; }; |
函数的声明如下:
|
1
|
void DeleteNode(ListNode *pListHead, ListNode *pToBeDeleted);
|
【分析】
这是一道广为流传的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)。
删除节点是最后一个节点:1* O(n)
删除节点不是最后一个节点:(n-1)*O(1)
总的时间复杂度T(n) =[(n-1)*O(1)+O(n)]/n= O(1)
【代码】
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
struct ListNode
{ int m_nKey; ListNode *m_pNext; }; void DeleteNode(ListNode *head, ListNode *toBeDeleted) if (toBeDeleted->m_pNext == NULL) ListNode *cur = head; // delete deleted node ListNode *next = toBeDeleted->m_pNext; // delete the node next to deleted |
值得注意的是,为了让代码看起来简洁一些,上面的代码基于两个假设:
(1)给定的结点的确在链表中;
(2)给定的要删除的结点不是链表的头结点。
不考虑第一个假设对代码的鲁棒性是有影响的。至于第二个假设,当整个列表只有一个结点时,代码会有问题。但这个假设不算很过分,因为在有些链表的实现中,会创建一个虚拟的链表头,并不是一个实际的链表结点。这样要删除的结点就不可能是链表的头结点了。当然,在面试中,我们可以把这些假设和面试官交流。这样,面试官还是会觉得我们考虑问题很周到的。
【参考】
http://zhedahht.blog.163.com/blog/static/254111742007112255248202/
33.在O(1)时间删除链表结点[DeleteListNode]的更多相关文章
- 程序员面试题精选100题(33)-在O(1)时间删除链表结点[数据结构]
作者:何海涛 出处:http://zhedahht.blog.163.com/ 题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点.链表结点的定义如下: struct ListNode { ...
- 【面试题013】在O(1)时间删除链表结点
[面试题013]在O(1)时间删除链表结点 我们要删除结点i,我们可以把结点i的下一个结点j的内容复制到结点i,然后呢把结点i的指针指向结点j的下一个结点.然后在删除结点j. 1.如果结点i位于链表 ...
- 剑指Offer面试题:12.在O(1)时间删除链表结点
一.题目:在O(1)时间删除链表结点 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 原文采用的是C/C++,这里采用C#,节点定义如下: public class ...
- 【Java】 剑指offer(17) 在O(1)时间删除链表结点
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除 ...
- 《剑指offer》第十八题(在O(1)时间删除链表结点)
// 面试题18(一):在O(1)时间删除链表结点 // 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该 // 结点. #include <iostream> ...
- 面试题18(一):在O(1)时间删除链表结点
// 面试题18(一):在O(1)时间删除链表结点 // 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该 // 结点.链表结点与函数的定义如下: // struct Lis ...
- 第18题:在O(1)时间删除链表结点+删除链表中重复的节点
题目描述:题目描述在O(1)时间删除链表结点 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 考查创新编程能力. 思路: 1.如果从头到尾遍历,时间O(n) 2.如果将待删 ...
- 剑指Offer:面试题13——在O(1)时间删除链表结点
问题描述: 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点.链表结点与函数的定义如下: public class ListNode{ int value; ListNode ...
- 在O(1)时间删除链表结点
题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 链表结点与函数的定义如下: struct ListNode { int m_nValue; ListNode* m_p ...
随机推荐
- 【FE前端学习】第二阶段任务-基础
技能学习部分: 1.需要熟练掌握HTML标签以及CSS各个常用属性. 2.掌握CSS3 常用属性 3.掌握jquery的基本用法,对于JS基本逻辑语句需要熟练掌握 上文 [FE前端学习]第二阶段任务- ...
- 【POJ 2484】A Funny Game
Description Alice and Bob decide to play a funny game. At the beginning of the game they pick n(1 &l ...
- 从svn服务器自动同步到另一台服务器
需求场景 A commit B post-commit C (workstation) --------------> (svn server) ---------------------> ...
- 【poj2724】 Purifying Machine
http://poj.org/problem?id=2724 (题目链接) 题意 Mike有一个机器可以帮助他清理奶酪,每个奶酪由一个n位二进制数表示,机器上一共有n个按钮,每个按钮有1,0,*,其中 ...
- codeforces 375D:Tree and Queries
Description You have a rooted tree consisting of n vertices. Each vertex of the tree has some color. ...
- codevs1225 八数码难题
题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在 3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数 ...
- [IOS UIalert模版]
1.alertview创建 UIAlertView *alert; alert = [[UIAlertView alloc] initWithTitle:@"提示" message ...
- Android:View中的performClick()触发条件
http://blog.sina.com.cn/s/blog_70ae1d7b0102v7uk.html 先看看performClick()源码: public boolean performCl ...
- 采用get的方式提交数据到服务器
1 效果演示:
- Ognl基本使用
---恢复内容开始--- Ognl默认是从“根”中取数据的 下面Demo中用的是 Ognl.getValue(String expression, Map context, Object root) ...