剑指offer代码分析——面试题13在O(1)内删除链表结点
时间:2022-05-03
本文章向大家介绍剑指offer代码分析——面试题13在O(1)内删除链表结点,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
本题详细解析都已在代码中注释了:
/**
* 给一个单链表,头指针为first,请用O(1)时间删除其中节点p
* @author chibozhou
*/
public class DeleteNode {
/**
* 分析:
* 删除单链表中的某一节点常规做法是:
* 从头开始扫描单链表,找到p节点的前一个节点q,然后做以下操作:
* q.next = p.next;
* p = null;
*
* 这种方法扫描了单链表,因此时间复杂度是O(n)。
* 下面我们寻找时间复杂度O(1)的方法。
*/
/**
* 方法一之所以耗时,是因为它在寻找p的前一个结点采用了遍历,
* 因此,只要提升寻找前一个结点的效率,就能提升整个算法的效率。
* 那么,是否有办法能够在O(1)时间内找到前一个结点呢?
*/
/**
* 厉害的方法如下:
* 将p后继结点的数据复制到p中,再删除p的后继结点即可!代码如下:
*/
public static <T> boolean deleteNode(Node<T> first, Node<T> p){
//若链表为空
if(first==null){
System.out.println("链表为空!");
return false;
}
//若p是最后一个结点,则只能遍历寻找p的前一个结点
//解析:上述复制后继结点删除p的方法,在删除过程中,需要用到p.next=p.next.next;
//若p已经是最后一个结点,则上述语句就会出现空指针异常,因此p为最后一个结点的情况要单独判断.
if(p.next == null){
Node<T> q = p;
while(p.next != null){
q = p;
p = p.next;
}
q.next = p.next;
p = null;
}
//若p不是最后一个结点,则将p后继结点的数据复制到p中,再删除p的后继结点
//解析:单链表是一种用于存储数据的物理结构,从逻辑上看和数组一样。
//要删除一个结点,从逻辑上看就是删除一个序列的某一个数据。因此,从逻辑上看,
//只要两个结点的数值相同,就认为这两个结点是相等的。
//因此,采用这种复制后继结点的方式删除结点,虽然删除后结点的存储位置发生了变化,
//但从逻辑角度看,只是删除了序列中的一个数。
if(p.next != null){
p.data = p.next.data;
p.next = p.next.next;
}
return true;
}
}
/**
* 定义结点
*/
class Node<T>{
public T data;
public Node<T> next;
}
- Spring Cloud Edgware新特性之七:可选的EnableDiscoveryClient注解
- 【LEETCODE】模拟面试-46. Permutations
- CentOS6 Upgrade Python
- Emacs setup for Go Development
- 【LEETCODE】模拟面试-39. Combination Sum
- Docker系列教程12-使用Maven插件构建Docker镜像
- Linux nohup 用法
- 【LEETCODE】模拟面试-84-Largest Rectangle in Histogram
- Docker系列教程11-使用Nexus管理Docker镜像
- Mac 配置终端环境
- 【LEETCODE】模拟面试-101-Symmetric Tree
- Docker系列教程10-使用Docker Registry管理镜像
- webapp开发调试环境--weinre配置
- AWK 深入浅出教程
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 关于laravel模板中生成URL的几种模式总结
- Laravel基础-关于引入公共文件的两种方式
- Laravel框架Blade模板简介及模板继承用法分析
- 基于Laravel 多个中间件的执行顺序详解
- 关于laravel 日志写入失败问题汇总
- 确保Laravel网站不会被嵌入到其他站点中的方法
- PHP PDO和消息队列的个人理解与应用实例分析
- tp5 sum某个字段相加得到总数的例子
- laravel框架创建授权策略实例分析
- tp5递归 无限级分类详解
- PHP 进程池与轮询调度算法实现多任务的示例代码
- 如何在Laravel5.8中正确地应用Repository设计模式
- laravel框架中路由设置,路由参数和路由命名实例分析
- PHP框架实现WebSocket在线聊天通讯系统
- 设定php简写功能的方法