用O(1)的时间复杂度删除单链表中的某个节点

给定链表的头指针和一个结点指针,在O(1)时间删除该结点。链表结点的定义如下:

struct ListNode
{int        m_nKey;ListNode*  m_pNext;
};

函数的声明如下:

void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted);

这是一道广为流传的Google面试题,考察我们对链表的操作和时间复杂度的了解,咋一看这道题还想不出什么较好的解法,但人家把题出在这,肯定是有解法的。一般单链表删除某个节点,需要知道删除节点的前一个节点,则需要O(n)的遍历时间,显然常规思路是不行的。在仔细看题目,换一种思路,既然不能在O(1)得到删除节点的前一个元素,但我们可以轻松得到后一个元素,这样,我们何不把后一个元素赋值给待删除节点,这样也就相当于是删除了当前元素。可见,该方法可行,但如果待删除节点为最后一个节点,则不能按照以上思路,没有办法,只能按照常规方法遍历,时间复杂度为O(n),是不是不符合题目要求呢?可能很多人在这就会怀疑自己的思考,从而放弃这种思路,最后可能放弃这道题,这就是这道面试题有意思的地方,虽看简单,但是考察了大家的分析判断能力,是否拥有强大的心理,充分自信。其实我们分析一下,仍然是满足题目要求的,如果删除节点为前面的n-1个节点,则时间复杂度为O(1),只有删除节点为最后一个时,时间复杂度才为O(n),所以平均的时间复杂度为:(O(1) * (n-1) + O(n))/n = O(1);仍然为O(1).下面见代码:

 1 /* Delete a node in a list with O(1)
 2  * input:    pListHead - the head of list
 3  *            pToBeDeleted - the node to be deleted
 4  */
 5
 6 struct  ListNode
 7 {
 8     int            m_nKey;
 9     ListNode*    m_pNext;
10 };
11
12 void DeleteNode(ListNode *pListHead, ListNode *pToBeDeleted)
13 {
14     if (!pListHead || !pToBeDeleted)
15         return;
16
17     if (pToBeDeleted->m_pNext != NULL) {
18         ListNode *pNext = pToBeDeleted->m_pNext;
19         pToBeDeleted->m_pNext = pNext->m_pNext;
20         pToBeDeleted->m_nKey = pNext->m_nKey;
21
22         delete pNext;
23         pNext = NULL;
24     }
25     else { //待删除节点为尾节点
26         ListNode *pTemp = pListHead;
27         while(pTemp->m_pNext != pToBeDeleted)
28             pTemp = pTemp->m_pNext;
29         pTemp->m_pNext = NULL;
30
31         delete pToBeDeleted;
32         pToBeDeleted = NULL;
33     }
34 }
转载自:http://www.cnblogs.com/bakari/p/4013812.html

用O(1)的时间复杂度删除单链表中的某个节点相关推荐

  1. 删除单链表中的重复节点

    删除单链表中的重复节点 一.题目描述 已知单链表L,写一算法,删除其中的重复节点.(更好的阅读体验,请访问程序员在旅途) 二.分析解答 2.1 知识点分析 本题主要考察链表的相关知识点,其中包括:单链 ...

  2. 删除单链表中的重复节点(c语言版本)

    这是一道经典的面试题,下面是我的研究和举一反三,特整理如下: 分为三种情形: (1)删除有序链表的重复节点,重复节点一个都不留 (2)删除有序链表的重复节点,重复节点只留一个 (3)删除无序链表的重复 ...

  3. 写一个函数DeleteRange删除单链表中结点的值在low 和high之间的结点

    /*实验2 1. 写一个函数DeleteRange删除单链表中结点的值在low 和high之间的结点 (low和high的值是多少可自由设计).并且要在程序中验证其功能实现. (可在实验1的第3题的基 ...

  4. python 链表倒数第k个节点_链表-删除单链表中倒数第k个节点

    题目 实现一个函数,一个可以删除单链表中倒数第k个节点 难度 简单 分析 本题比较简单,实现方法多种多样,这里提供一种方法 首先明确一点,在单链表中删除倒数第k个节点,需要找到他的前一个节点,让前一个 ...

  5. 删除单链表中倒是第K个结点

    [问题描述] 设有头结点单链表,删除单链表中倒数第k个结点. [输入形式] 第一行输入若干个整数建立带头结点的单链表(以输入字符作为结束). 第二行输入一个整数k,表示删除倒数第k个结点. [输出形式 ...

  6. 【IT笔试面试题整理】删除无序链表中重复的节点

    [试题描述]定义一个函数,输入一个链表,删除无序链表中重复的节点 [参考代码] 方法一: Without a buffer, we can iterate with two pointers: &qu ...

  7. 递归删除单链表中所有值为x的元素_如何纯递归反转链表的一部分

    读完本文,你可以去力扣拿下如下题目: 92.反转链表II ----------- 反转单链表的迭代实现不是一个困难的事情,但是递归实现就有点难度了,如果再加一点难度,让你仅仅反转单链表中的一部分,你是 ...

  8. C++删除单链表中指定元素

    // 删除单链表指定元素5 #include <iostream> #include <vector> using namespace std;//节点定义: struct L ...

  9. 西电数据结构上机题目-删除单链表中介于min与max之间的结点

    希望学长的代码能给大二西电er们带来帮助(大家一定要好好学习数据结构,合理利用资源) 大家找到了什么bug或有什么改进意见可以私信我或在下方留言,我都会看的 不多说废话直接上代码 #include&l ...

最新文章

  1. python写接口自动化需要rsa加密_RSA加密,请问如何用Python实现该加密过程
  2. js向jsp传中文出现乱码的解决方法
  3. 2d绘制 c# dx_C# 从零开始写 SharpDx 应用 绘制基础图形
  4. 产品经理如何做好需求挖掘
  5. 年末盘点,2021年最值得推荐的10个提高开发效率工具,程序员必备
  6. 计算机字处理软件word文档,2012计算机字处理软件 Word(answer)
  7. python import模块熟悉方法
  8. Apache Hive 下载与安装
  9. apple id 如何注册来啦?(亲测流程)
  10. 扒一扒那些叫欧拉的定理们(一)——基本介绍和简单多面体欧拉定理
  11. 倍加福光电传感器OBE10M-18GM60-SE5-V1
  12. 规范国内省份名称【Java】
  13. wifidog 源码初分析
  14. android auto谷歌地图,如何在 Android Auto 中使用 Waze 而不是谷歌地图
  15. 螺旋无限延伸_八卦中的双螺旋结构,无限大∞符号隐含的秘密
  16. 大学生考华为ICT认证,从哪个级别开始
  17. 对象,构造函数,构造函数小练习
  18. 微信小程序module.exports 模块化
  19. 计算机 发声原理,耳机 篇十五:动铁耳机发声原理哦。喜欢记得收藏。
  20. 面向嵌入式开发的C++中间件库

热门文章

  1. django+nginx+uwsgi部署web站点
  2. 独家 | 一文读懂自然语言处理NLP(附学习资料)
  3. StringBuffer与StringBuilder
  4. HAproxy + Keepalive实现LDAP代理服务
  5. Android 调用分享框
  6. AaronYang WCF教程目录
  7. 手机吞吃蛇游戏的设计与开发
  8. 圆锥曲线万能弦长公式_2020高考数学50条秒杀型公式与方法
  9. java dump分析工具_Java 性能分析工具 (2):Java 内置监控工具
  10. python cross val score_sklearn函数:cross_val_score(交叉验证评分)