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

自己所写代码如下:

//以O(1)时间删除链表节点
//要求:单向链表,头指针,待删节点指针 //链表节点
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
//O(n)的解法:从头遍历,找到pToBeDeleted所指节点的前一个节点再进行删除
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
if(pListHead == NULL || *pListHead == NULL || pToBeDeleted == NULL)
return; ListNode* pNode = *pListHead;
if(pNode == pToBeDeleted) //对pToBeDeleted指向头结点情况的处理
{
*pListHead = (*pListHead)->m_pNext;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
else
{
while(pNode->m_pNext != NULL && pNode->m_pNext != pToBeDeleted)
pNode = pNode->m_pNext ; if(pNode->m_pNext == NULL)
{
cout<<"pToBeDeleted不在链表中!"<<endl;
return;
} pNode->m_pNext = pToBeDeleted->m_pNext;
delete pToBeDeleted;
pToBeDeleted = NULL; } } //O(1)的解法:复制后一个节点以覆盖待删节点,再删除重复的后一个节点
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
if(pListHead == NULL || *pListHead == NULL || pToBeDeleted == NULL)
return; ListNode* pNode = *pListHead;
if(pNode == pToBeDeleted)
{
*pListHead = (*pListHead)->m_pNext;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
else
{
pNode = pToBeDeleted->m_pNext;
//排除pToBeDeleted指向尾节点的情形
if(pNode == NULL)
{
pNode = *pListHead;
while(pNode->m_pNext != pToBeDeleted)
pNode = pNode->m_pNext ; pNode->m_pNext = NULL; delete pToBeDeleted;
pToBeDeleted = NULL;
}
else
{
pToBeDeleted->m_nValue = pNode->m_nValue;
pToBeDeleted->m_pNext = pNode->m_pNext;
delete pNode;
pNode = NULL;
} }
}

在以上O(1)的代码中,自己的想法有些呆板,具体来说:采用复制覆盖的方法则应考虑的是pToBeDeleted指向尾节点的特殊情况(此时,无法复制!)

而非pToBeDeleted指向头结点的情况(这是O(n)的特殊情况!)!!!

O(n)的方法:需要找前驱节点,所以考虑头结点的特殊情况;

O(1)的方法:需要找后继节点,所以考虑尾节点的特殊情况。

代码修改如下:

//O(1)的解法:复制后一个节点以覆盖待删节点,再删除重复的后一个节点
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
if(pListHead == NULL || *pListHead == NULL || pToBeDeleted == NULL)
return; ListNode* pNode = pToBeDeleted->m_pNext;
//排除pToBeDeleted指向尾节点的情形
if(pNode == NULL)
{
pNode = *pListHead;
if(pNode == pToBeDeleted)
{
delete pToBeDeleted;
*pListHead = pToBeDeleted = NULL;
}
else
{
while(pNode->m_pNext != pToBeDeleted)
pNode = pNode->m_pNext; pNode->m_pNext = NULL; delete pToBeDeleted;
pToBeDeleted = NULL;
} }
else
{
pToBeDeleted->m_nValue = pNode->m_nValue;
pToBeDeleted->m_pNext = pNode->m_pNext;
delete pNode;
pNode = NULL;
} }

和参考代码相一致!赞一个!

总结:1、突破常规思维,删除节点不一定需要从头遍历链表,可以用下一结点复制并覆盖待删节点,最后再删除重复的下一结点。

   2、考虑问题全面性:若待删节点为尾节点,则下一个节点为空;若整个链表仅一个节点,删除后,头结点同时设为NULL。

      这些都需要特殊对待!!!

剑指offer--面试题13的更多相关文章

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

    问题描述: 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点.链表结点与函数的定义如下: public class ListNode{ int value; ListNode ...

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

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

  3. 剑指Offer——笔试题+知识点总结

    剑指Offer--笔试题+知识点总结 情景回顾 时间:2016.9.23 12:00-14:00 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:笔试 注意事项:要有大局观, ...

  4. C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告

    剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...

  5. C++版 - 剑指offer 面试题23:从上往下打印二叉树(二叉树的层次遍历BFS) 题解

    剑指offer  面试题23:从上往下打印二叉树 参与人数:4853  时间限制:1秒  空间限制:32768K 提交网址: http://www.nowcoder.com/practice/7fe2 ...

  6. C++版 - 剑指offer 面试题39:判断平衡二叉树(LeetCode 110. Balanced Binary Tree) 题解

    剑指offer 面试题39:判断平衡二叉树 提交网址:  http://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId= ...

  7. Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)

    剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...

  8. C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解

    剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...

  9. C++版 - 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解

    剑指offer 面试题24:二叉搜索树的后序遍历序列(的判断) 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true.否则返回false.假设输入的数组的任意两个 ...

  10. C++版 - 剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题,ZOJ 1088:System Overload类似)题解

    剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题) 原书题目:0, 1, - , n-1 这n个数字排成一个圈圈,从数字0开始每次从圆圏里删除第m个数字.求出这个圈圈里剩下的最后一个数字 ...

随机推荐

  1. jQuery 删除或是清空某个HTML元素示例

    jQuery使用下面两个方法来删除或是清空某个HTML元素. remove() – 删除指定的元素(包括其子元素)empty() – 清空指定元素的子元素 1.remove()  <!DOCTY ...

  2. Objective-C设计模式——原型Prototype(对象创建)

    1.原型 原型设计模式所谓原型设计模式,其实就是对象复制,这个特性在所有语言基本上都是存在的. 我们知道在OC中,对象赋值其实是对对象的引用复制,其实就是相当于C语言中的指针.创建了一个新的变量,但是 ...

  3. HTML+CSS学习笔记 (12) - CSS布局模型

    标签:HTML+CSS css布局模型 清楚了CSS 盒模型的基本概念. 盒模型类型, 我们就可以深入探讨网页布局的基本模型了.布局模型与盒模型一样都是 CSS 最基本. 最核心的概念. 但布局模型是 ...

  4. 延迟加载(Lazy Load)

    一个对象,它虽然不包含所需要的所有数据,但是它知道怎么获取这些数据 设计专门的对象来把数据从DB中加载到内存中. 该对象可以完成在加载所需对象的同时,把与之相关的对象也一并加载了. 否则,必须显示加载 ...

  5. (转)hessian源码分析(一)------架构

    在计费中心的对外交互这块采用了hessian,有必要对hessian的运行机理和源码做一定的解析. 大致翻了翻源码后,发现hessian的主要结构分客户端与服务端,中间基于http传输.客户端主要做的 ...

  6. Java 字符流实现文件读写操作(FileReader-FileWriter)

    Java 字符流实现文件读写操作(FileReader-FileWriter) 备注:字符流效率高,但是没有字节流底层 字节流地址:http://pengyan5945.iteye.com/blog/ ...

  7. ArcGIS10中matplotlib画图时的中文设置

    利用GIS的数据批量生成XY的图形图像文件,可以直接使用Python.一般大家都是用matplotlib,中文设置的问题参看了许多内容,结论是对错不一,让我折腾了三天,现总结如下: 1.软件的版本.安 ...

  8. C# 语言如何获取json格式的数据,不用javascript用c#实现。。。

    {'state' : 1,'data':{'list':[{'id': 123, 'name': '诸葛天邪','level': 10,'country': 1,}]}} 比如我要获取里面的 id 该 ...

  9. 2013-07-29 IT 要闻速记快想

    ### ========================= ###传动视暴雪82亿美元赎身,腾讯参与投资 ### ========================= ###帮助企业解决打印&邮 ...

  10. centOS 一键php环境安装-php博弈

    我是方少,闲着没事,感觉每次编译安装,再修改php,mysql,redis,nginx配置文件觉得把大好的青春时间都浪费掉了.如是想着,怎样一键安装 php环境和相关配置.于是拜读了一下lnmp的一键 ...