// 面试题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)时间删除链表结点的更多相关文章

  1. 【面试题013】在O(1)时间删除链表结点

    [面试题013]在O(1)时间删除链表结点  我们要删除结点i,我们可以把结点i的下一个结点j的内容复制到结点i,然后呢把结点i的指针指向结点j的下一个结点.然后在删除结点j. 1.如果结点i位于链表 ...

  2. 剑指Offer面试题:12.在O(1)时间删除链表结点

    一.题目:在O(1)时间删除链表结点 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 原文采用的是C/C++,这里采用C#,节点定义如下: public class ...

  3. 第18题:在O(1)时间删除链表结点+删除链表中重复的节点

    题目描述:题目描述在O(1)时间删除链表结点 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 考查创新编程能力. 思路: 1.如果从头到尾遍历,时间O(n) 2.如果将待删 ...

  4. P99、面试题13:在o(1)时间删除链表结点

    题目:给定单向链表的头指针和一个结点指针,定义一个函数在o(1)时间删除该结点.链表结点与函数的定义如下:struct ListNode{       int m_nValue;       List ...

  5. 面试题13:在O(1)时间删除链表结点

    题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 链表结点与函数的定义如下: struct ListNode { int val; ListNode* next; }; ...

  6. 【剑指offer 面试题13】在 O(1) 时间删除链表结点

    #include <iostream> using namespace std; //构造链表结点 struct ListNode { int val; ListNode *next; L ...

  7. 【Java】 剑指offer(17) 在O(1)时间删除链表结点

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除 ...

  8. 《剑指offer》第十八题(在O(1)时间删除链表结点)

    // 面试题18(一):在O(1)时间删除链表结点 // 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该 // 结点. #include <iostream> ...

  9. 程序员面试题精选100题(33)-在O(1)时间删除链表结点[数据结构]

    作者:何海涛 出处:http://zhedahht.blog.163.com/ 题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点.链表结点的定义如下: struct ListNode { ...

随机推荐

  1. dedecms 织梦点击图片进入下一页代码

    织梦DedeCMS5.6网站文章页点击图片进入下一页最后一页进入下一篇文章的方法: 我们首先按照下面的方法修改: 修改 include/arc.archives.class.php 1.查找“//解析 ...

  2. [转]Tomcat启动分析

    [转]Tomcat启动分析 原帖 http://docs.huihoo.com/apache/tomcat/heavyz/01-startup.html 以下摘录了部分 --------------- ...

  3. NTFS文件系统的主要优点体现在以下三个方面

    1.NFTS格式具有用户权限的控制管理功能 2.NTFS有更好的压缩率 3.NTFS具有日志功能,可以提高系统安全性

  4. spring学习(3)

    bean的声明周期 为什么把生命周期当做一个重点? Servlet->servlet生命周期 Servlet生命周期分为三个阶段: 1:初始化阶段,调用init()方法 2:响应客户请求阶段,调 ...

  5. C++(八)— 死锁原因及解决方法

    1.死锁原因 死锁问题被认为是线程/进程间切换消耗系统性能的一种极端情况.在死锁时,线程/进程间相互等待资源,而又不释放自身的资源,导致无穷无尽的等待,其结果是任务永远无法执行完成. 打个比方,假设有 ...

  6. Selenium-鼠标操作

    有些特殊的系统可能需要模拟键盘或者鼠标的操作才可以 鼠标的操作不仅仅是click()单击操作,还有很多包含在ActionChains类中 context_click(elem) 右击鼠标点击元素ele ...

  7. JavaUtil_06_HttpUtil_使用httpclient实现

    一.简介 使用 appache 的 httpclient 来实现的 二.源码 package com.ray.weixin.gz.util; import java.io.File; import j ...

  8. 【ACM-ICPC 2018 徐州赛区网络预赛】D.Easy Math 杜教筛

    代码 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 20000000; ...

  9. QWidget上下文菜单处理函数

    QWidget类是Qt中所有可视化部件的基类,其很多函数都是虚函数,能被子类重写以表现不同形式和功能,今天来学习一下QWdiget的事件处理函数. 事件是鼠标.键盘或系统因其自身某些状态发生改变而引起 ...

  10. 2016北京集训 小Q与进位制

    题目大意 一个数每一位进制不同,已知每一位的进制,求该数的十进制表达. 显然有 $$Ans=\sum\limits_{i=0}^{n-1}a_i \prod\limits_{j=0}^{i-1}bas ...