18.1 在 O(1) 时间内删除链表节点(剑指 Offer 题解Java版)

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

题目描述

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

解题思路

① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,然后令该节点指向下下个节点,再删除下一个节点,时间复杂度为 O(1)。
在这里插入图片描述
② 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向 null,时间复杂度为 O(N)。
在这里插入图片描述
综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个尾节点以 O(N) 的时间复杂度操作节点的总次数。(2N-1)/N ~ 2,因此该算法的平均时间复杂度为 O(1)。

测试用例

功能测试(多个结点链表,删除头结点、中间结点和尾结点;单个结点链表)
特殊测试(头结点或删除结点为null)

package 剑指offer.在O时间内删除链表节点;/*
作者     :XiangLin
创建时间 :03/04/2020 20:08
文件     :Offer18_01.java
IDE      :IntelliJ IDEA
*/

public class Offer18_01 {
    static class ListNode{
        public int value;
        public ListNode next;

        public ListNode(){

        }

        public ListNode(int value,ListNode next){
            this.value = value;
            this.next = next;
        }
    }
    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 Soluton1(phead,pdelNode);
    }
    /**
     * 如果要删除的节点是中间节点,我们可以直接将它后面的一个节点的值赋给它, 而要删除的节点就变成了它后面的一个节点,
     * 要考虑删除节点是尾结点,和链表中只有一个节点的情况
     *
     * @param phead
     * @param pdelNode
     * @return
     */

    private static ListNode Soluton1(ListNode phead, ListNode pdelNode) {
        if (phead == null || pdelNode == null){
            return phead;
        }
        if (pdelNode.next != null){// 要删除的节点在链表中间位置
            ListNode p = pdelNode.next;
            pdelNode.value = p.value; //注意顺序不能错
            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){
                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.value + " ");
            p = p.next;
        }
        System.out.println();
    }
}

在这里插入图片描述
所有巧合的是要么是上天注定要么是一个人偷偷的在努力。

公众号,关注回复【电子书】有惊喜,资源多多。

个人微信公众号,专注于学习资源、笔记分享,欢迎关注。我们一起成长,一起学习。一直纯真着,善良着,温情地热爱生活,,如果觉得有点用的话,请不要吝啬你手中点赞的权力,谢谢我亲爱的读者朋友
五角钱的程序员,专注于学习资源、笔记分享。

The only person you need to compare yourself to is who you have been. The only person you need to be better than is who you are.
你需要跟自己比的唯一一个人,就是曾经的自己。你需要比一个人变得更好,那个人就是现在的你。

给大家推荐一个Github,上面非常非常多的干货,保证让你满意:https://github.com/XiangLinPro/IT_book

2020年4月3日于重庆城口
好好学习,天天向上,终有所获

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值