剑指offer--面试题13
题目:以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的更多相关文章
- 剑指Offer:面试题13——在O(1)时间删除链表结点
问题描述: 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点.链表结点与函数的定义如下: public class ListNode{ int value; ListNode ...
- 【剑指offer 面试题13】在 O(1) 时间删除链表结点
#include <iostream> using namespace std; //构造链表结点 struct ListNode { int val; ListNode *next; L ...
- 剑指Offer——笔试题+知识点总结
剑指Offer--笔试题+知识点总结 情景回顾 时间:2016.9.23 12:00-14:00 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:笔试 注意事项:要有大局观, ...
- C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告
剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...
- C++版 - 剑指offer 面试题23:从上往下打印二叉树(二叉树的层次遍历BFS) 题解
剑指offer 面试题23:从上往下打印二叉树 参与人数:4853 时间限制:1秒 空间限制:32768K 提交网址: http://www.nowcoder.com/practice/7fe2 ...
- C++版 - 剑指offer 面试题39:判断平衡二叉树(LeetCode 110. Balanced Binary Tree) 题解
剑指offer 面试题39:判断平衡二叉树 提交网址: http://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId= ...
- Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)
剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...
- C++版 - 剑指Offer 面试题39:二叉树的深度(高度)(二叉树深度优先遍历dfs的应用) 题解
剑指Offer 面试题39:二叉树的深度(高度) 题目:输入一棵二叉树的根结点,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度.例如:输入二叉树 ...
- C++版 - 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解
剑指offer 面试题24:二叉搜索树的后序遍历序列(的判断) 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true.否则返回false.假设输入的数组的任意两个 ...
- C++版 - 剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题,ZOJ 1088:System Overload类似)题解
剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题) 原书题目:0, 1, - , n-1 这n个数字排成一个圈圈,从数字0开始每次从圆圏里删除第m个数字.求出这个圈圈里剩下的最后一个数字 ...
随机推荐
- sql server 修改列类型
如下代码中为修改bcp数据库中表B_TaskFileMonitor中的列FileSizeOriginal的类型为bigint use bcp; ); --判断是否存在这一列 IF COL_LENGTH ...
- android 网络_网络图片查看器
xml <?xml version="1.0"?> -<LinearLayout tools:context=".MainActivity" ...
- IOS绘图
#import "ViewController.h" #import "DrawView.h" @interface ViewController () @pr ...
- nginx配置多个网址
实战Nginx与PHP(FastCGI)的安装.配置与优化:http://ixdba.blog.51cto.com/2895551/806622 Nginx配置文件详细说明:http://www.cn ...
- wordpress 在linux上配置固定url方法
wordpress 设置固定url总结 相信好多用wordpress的网友为了提升wordpress对搜索引擎的友好,或者是为了写的博客地址更好记,都会在wordpress的后台设置固定url的方式. ...
- CenterOS中安装Redis及开机启动设置
Redis安装 从官方下载最新Redis进行安装,官网地址:http://redis.io/download $ wget http://download.redis.io/releases/redi ...
- Delphi XE5教程10:Delphi字符集
内容源自Delphi XE5 UPDATE 2官方帮助<Delphi Reference>,本人水平有限,欢迎各位高人修正相关错误!也欢迎各位加入到Delphi学习资料汉化中来,有兴趣者可 ...
- Delphi 二次开发 CorelDRAW
我们首先通过一个简单的程序例子来看一下Delphi对CorelDRAW二次开发有什么样的效果.本程序实现CorelDRAW程序的打开和关闭. 1.1 Delphi与CorelDRAW连接 在程序与Co ...
- Response.Redirect和Server.Transfer
今天又比较闲,逛了逛园子,看看asp.net的内容,看到一篇关于这两个的比较: http://www.cnblogs.com/yunfeng8967/archive/2008/03/06/109323 ...
- Struct是干什么的
对于结构(Struct)这一看起来比较特殊的东西(用的比较少,只好用东西来形容了),真心用得少,只有在被问起的时候,才会想起,看看它到底是什么吧. 先给一个链接:http://www.cnblogs. ...