【Offer】[18-1] 【在O(1)时间内删除链表节点】
题目描述
给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。
思路分析
一般我们删除单链表中的节点是需要遍历链表,找到要删除节点的前一个元素,但是那样的时间复杂度为O(n),要在O(1)的时间内删除给出的节点,我们可以将删除节点p的下一个结点的值赋给p ,而我们只要删除p的下一个结点就可以了,同时我们还要注意边界值:
- 要删除的节点p是尾结点,
- 要删除的链表中只有一个节点 等特殊情况
测试用例
- 功能测试(多个结点链表,删除头结点、中间结点和尾结点;单个结点链表)
- 特殊测试(头结点或删除结点为null)
## Java代码
public class Offer18_01 {
public static void main(String[] args) {
System.out.println("****功能测试***");
test1();
System.out.println("***仅有一个节点元素的单链表测试***");
test2();
System.out.println("***特殊输入测试****");
test3();
}
public static ListNode deleteNodeInList(ListNode pHead, ListNode pdelNode) {
return Solution1(pHead, pdelNode);
}
/**
* 如果要删除的节点是中间节点,我们可以直接将它后面的一个节点的值赋给它, 而要删除的节点就变成了它后面的一个节点,
* 要考虑删除节点是尾结点,和链表中只有一个节点的情况
*
* @param pHead
* @param pdelNode
* @return
*/
private static ListNode Solution1(ListNode pHead, ListNode pdelNode) {
if (pHead == null || pdelNode == null) {
return pHead;
}
if (pdelNode.next != null) {// 要删除的节点在链表中间位置
ListNode p = pdelNode.next;
pdelNode.val = p.val;
pdelNode.next = p.next;
p = null;
} else if (pHead.next == pdelNode) {// 链表只有一个结点
pHead.next = pdelNode.next;
pdelNode = null;
} else {// 链表中有多的节点,要删除的节点是尾结点
ListNode p = pHead;
while (p.next != pdelNode) {// 搜寻pdelNode的前一个节点
p = p.next;
}
p.next = pdelNode.next;
pdelNode = null;
}
return pHead;
}
/**
* 功能测试
*/
private static void test1() {//
System.out.println("(不加头结点)有三个节点元素的单链表");
ListNode node3 = new ListNode(9, null);
ListNode node2 = new ListNode(2, node3);
ListNode node1 = new ListNode(4, node2);
ListNode pHead = new ListNode(-1, node1);// 头结点
System.out.println("删除之前");
printListNode(pHead);
System.out.println("删除之后--->");
deleteNodeInList(pHead, node2);
printListNode(pHead);
}
private static void test2() {//
System.out.println("(不加头结点)仅有一个节点元素的单链表");
ListNode node1 = new ListNode(4, null);
ListNode pHead = new ListNode(-1, node1);// 头结点
System.out.println("删除之前");
printListNode(pHead);
System.out.println("删除之后-->");
deleteNodeInList(pHead, node1);
printListNode(pHead);
}
/**
* 特殊输入测试
*/
private static void test3() {//
System.out.println("(不加头结点)有三个节点元素的单链表");
ListNode node3 = new ListNode(9, null);
ListNode node2 = new ListNode(2, node3);
ListNode node1 = new ListNode(4, node2);
ListNode pHead = new ListNode(-1, node1);// 头结点
System.out.println("删除之前");
printListNode(pHead);
System.out.println("删除之后(传入参数为null,null)--->");
deleteNodeInList(null, null);
printListNode(pHead);
}
/**
* 打印链表
*
* @param pHead
*/
private static void printListNode(ListNode pHead) {
ListNode p = pHead.next;
while (p != null) {
System.out.print(p.val + " ");
p = p.next;
}
System.out.println();
}
}
代码链接
【Offer】[18-1] 【在O(1)时间内删除链表节点】的更多相关文章
- 在O(1)的时间内删除链表节点
题目: 在O(1)的时间内删除链表节点.给定链表的头指针和待删除的节点指针,定义一个函数在O(1)的时间内删除该节点. 剑指offer的思路,顿时觉得极妙.删除节点node1,先把其下一个节点node ...
- JZ-069-在 O(1) 时间内删除链表节点
在 O(1) 时间内删除链表节点 题目描述 在 O(1) 时间内删除链表节点. 方案:如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,然后令该节点指向下下个节点,再删除下一个节点,时间复 ...
- 剑指offer编程题Java实现——面试题13在O(1)时间内删除链表节点
题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点. 由于给定的是单向链表,正常删除链表的时间复杂度是查找链表的时间复杂度即O(n),如果要求在O(1)时间复杂度内删除节点 ...
- 剑指offer.在O(1)时间内删除链表节点
给定单向链表的一个节点指针,定义一个函数在O(1)时间删除该结点.假设链表一定存在,并且该节点一定不是尾节点. 样例 输入:链表 1->4->6->8 删掉节点:第2个节点即6(头节 ...
- 13 在 O(1) 时间内删除链表节点
删除链表的一个结点,用下一个结点覆盖掉要删除的结点,再释放掉要删结点的下一个结点的内存 Java: public ListNode deleteNode(ListNode head, ListNode ...
- 每天一道算法题(4)——O(1)时间内删除链表节点
1.思路 假设链表......---A--B--C--D....,要删除B.一般的做法是遍历链表并记录前驱节点,修改指针,时间为O(n).删除节点的实质为更改后驱指针指向.这里,复制C的内容至B(此时 ...
- 基于visual Studio2013解决面试题之0604O(1)时间复杂度删除链表节点
题目
- [刷题] 剑指offer 面试题18:删除链表节点
要求 给定单向链表的头指针和一个节点指针,在O(1)时间内删除该节点 常规思路:从头节点a开始顺序遍历,发现p指向要删除的节点i,然后把p的m_pNext指向i的下一个节点j,时间复杂度O(n) O( ...
- 【编程题目】在 O(1)时间内删除链表结点
60.在 O(1)时间内删除链表结点(链表.算法).题目:给定链表的头指针和一个结点指针,在 O(1)时间删除该结点.链表结点的定义如下:struct ListNode{int m_nKey;List ...
随机推荐
- Python Iterator and Generator
Python Iterator and Generator Iterator 迭代器(Iterator)和可迭代对象(Iterable)往往是绑定的.可迭代对象就是我们平时经常用的list ,st ...
- 大厂面试Kafka,一定会问到的幂等性
01 幂等性如此重要 Kafka作为分布式MQ,大量用于分布式系统中,如消息推送系统.业务平台系统(如结算平台),就拿结算来说,业务方作为上游把数据打到结算平台,如果一份数据被计算.处理了多次,产生的 ...
- Mysql 局域网连接设置——Windows
在公司工作中,会遇到mysql数据库存储于某个人的电脑上,大家要想连接mysql服务,装有mysql服务的电脑就必须开启远程连接. 其实不仅仅是局域网,只要你有数据库所在服务器的公网IP地址都能连上. ...
- 洛谷 P2152 [SDOI2009]SuperGCD
题意简述 求两个整数a,b的最大公约数0 < a , b ≤ 10 ^ 10000. 题解思路 如果 a % 2 == 0 && b % 2 == 0 gcd(a,b) = gc ...
- Javasrcipt中从一个url或者从一个字符串中获取参数值得方法
从url中获取参数值是che程序开发过程中的常用需求,偶然得闲,便抽空研究了一下javasrcipt下,获取参数的办法(JAVA中也类似). 首先看url的规范: URL组成:protocol :// ...
- 基于注解的SpringAOP源码解析(三)
注意,读完本篇文章需要很长很长时间 在之前的2篇文章:AOP源码分析(一)AOP源码分析(二) 中,我们搭建了SpringAOP源码分析的环境,介绍了@EnableAspectJAutoProxy注解 ...
- Gradle——创建简单的项目
项目 & 任务 Gradle 的一切都是基于项目和任务的. 构建由一个或多个项目组成.项目的概念很抽象,它取决于你要用Gradle 做什么 .项目可以是 一个 Jar 库或者一个 web 程序 ...
- Day 07--最终修改(三)
2.明天着重学一下逻辑层的语法,以及界面层的数据绑定,与队友交流进度 3.今天修改也终于完成,除了搞c++以外的全部身心都放在这个东西身上也觉得它有点难搞,说明计算机不是吃素的.甚至在使用xml语法的 ...
- 一句道破所有的springmvc(面试必备)
springmvc流程 : URL--------前端控制器DispatcherServlet---------HandlerMapping处理器映射器-------调用HandlerAdapter处 ...
- 缓存系列-Redis入门教程
Redis是什么? Redis (REmote DIctionary Server)是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列,是一个高性能的key-valu ...