题目描述

  给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。

思路分析

  一般我们删除单链表中的节点是需要遍历链表,找到要删除节点的前一个元素,但是那样的时间复杂度为O(n),要在O(1)的时间内删除给出的节点,我们可以将删除节点p的下一个结点的值赋给p ,而我们只要删除p的下一个结点就可以了,同时我们还要注意边界值:

  1. 要删除的节点p是尾结点,
  2. 要删除的链表中只有一个节点 等特殊情况

测试用例

  1. 功能测试(多个结点链表,删除头结点、中间结点和尾结点;单个结点链表)
  2. 特殊测试(头结点或删除结点为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代码-Java

【Offer】[18-1] 【在O(1)时间内删除链表节点】的更多相关文章

  1. 在O(1)的时间内删除链表节点

    题目: 在O(1)的时间内删除链表节点.给定链表的头指针和待删除的节点指针,定义一个函数在O(1)的时间内删除该节点. 剑指offer的思路,顿时觉得极妙.删除节点node1,先把其下一个节点node ...

  2. JZ-069-在 O(1) 时间内删除链表节点

    在 O(1) 时间内删除链表节点 题目描述 在 O(1) 时间内删除链表节点. 方案:如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,然后令该节点指向下下个节点,再删除下一个节点,时间复 ...

  3. 剑指offer编程题Java实现——面试题13在O(1)时间内删除链表节点

    题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点. 由于给定的是单向链表,正常删除链表的时间复杂度是查找链表的时间复杂度即O(n),如果要求在O(1)时间复杂度内删除节点 ...

  4. 剑指offer.在O(1)时间内删除链表节点

    给定单向链表的一个节点指针,定义一个函数在O(1)时间删除该结点.假设链表一定存在,并且该节点一定不是尾节点. 样例 输入:链表 1->4->6->8 删掉节点:第2个节点即6(头节 ...

  5. 13 在 O(1) 时间内删除链表节点

    删除链表的一个结点,用下一个结点覆盖掉要删除的结点,再释放掉要删结点的下一个结点的内存 Java: public ListNode deleteNode(ListNode head, ListNode ...

  6. 每天一道算法题(4)——O(1)时间内删除链表节点

    1.思路 假设链表......---A--B--C--D....,要删除B.一般的做法是遍历链表并记录前驱节点,修改指针,时间为O(n).删除节点的实质为更改后驱指针指向.这里,复制C的内容至B(此时 ...

  7. 基于visual Studio2013解决面试题之0604O(1)时间复杂度删除链表节点

     题目

  8. [刷题] 剑指offer 面试题18:删除链表节点

    要求 给定单向链表的头指针和一个节点指针,在O(1)时间内删除该节点 常规思路:从头节点a开始顺序遍历,发现p指向要删除的节点i,然后把p的m_pNext指向i的下一个节点j,时间复杂度O(n) O( ...

  9. 【编程题目】在 O(1)时间内删除链表结点

    60.在 O(1)时间内删除链表结点(链表.算法).题目:给定链表的头指针和一个结点指针,在 O(1)时间删除该结点.链表结点的定义如下:struct ListNode{int m_nKey;List ...

随机推荐

  1. Jenkins 配置 SpringBoot 自动构建部署

    服务器版本 Linux version 3.10.0-957.12.1.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8 ...

  2. 理解MySQL(二)--数据库事务

    1.事务:事务内的语句,要么全部执行成功,要么全部执行失败. a)      数据库事务四要素:ACID,原子性,一致性,隔离性,持久性. b)      原子性:一个事务必须被视为不可分割的最小单元 ...

  3. [原创实践]redhat linux 5.3搭建Nexus

    1:下载安装JDK,配置好环境变量(JAVA_HOME等) 下载linux下64位的jdk-7u45-linux-x64.tar.gz(百度网盘下载,官网的jdk-7u51-linux-x64.tar ...

  4. Java——数据结构(顺序表)

    这是一个顺序表的类,初始化的时候就已经确定了表的长度,之后不能添加数据,因为使用的是数组存储的数据,不过这个表的类型是泛型的. public class List { private Object[] ...

  5. Java虚拟机(二)-对象创建

    这一篇大致说明一下,对象在Java堆中对象分配.内存布局以及访问定位 1.对象的创建 虚拟机在遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引 ...

  6. js实现图片上传方法

    知识点 onchange事件 循环 封装函数 ajax php Javascript代码 //找到元素 var file=document.getElementById("file" ...

  7. abap简单实现form递归

    需求:根据物料号查询下层物料清单 DATA LV_MATNR LIKE ZMARA_TEST-MATNR VALUE '000000000000000001'. DATA: LT_MAT LIKE T ...

  8. 2017版 Jetbrains 系列软件激活方法

    1. 到网站 http://idea.lanyus.com/ 获取注册码. 2.填入下面的license server: http://intellij.mandroid.cn/ http://ide ...

  9. 我是如何学习写一个操作系统(二):操作系统的启动之Bootloader

    前言 今天本来的任务看书和把之前写的FragileOS整理一下,但是到现在还在摸鱼,书也只看一点.后来整理了一下写这个系列的思路,原本的目的是对操作系统原理性的学习和对之前写的一个玩具型操作系统的回顾 ...

  10. 轻松pick移动开发第二篇,rem布局

    一.为什么要使用rem布局 前面我写了flex布局的优点,分配伸缩盒容器中子盒子占的份数及排列方式,使其不受屏幕缩放的影响,使布局变得简单.然而,在有些时候,不可避免要给盒子设置高度的值,怎么让高度也 ...