剑指OFFER笔记_18_删除链表的节点_JAVA实现

本文介绍了一种在O(1)时间内删除链表中指定节点的方法,包括删除非尾节点、尾节点和仅有头节点的特殊情况,提供了JAVA实现代码及测试案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:删除链表的节点

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

解题思路

  • 若给定了节点指针,则不需要遍历整张链表以寻找当前的node。
  • 只需要将node的下一个节点用来替换node,node的next指向原node下一个节点的next。

代码

ListNode结构代码

package q18_01;

public class ListNode {
    public int val;
    public ListNode next;
    public ListNode(int x) {
        val = x;
    }
}

函数主体部分代码

package q18_01;

/**
 * 给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。
 */
public class Solution {
    /**
     * 删除指定节点
     * @param head
     * @param nodeToDelete
     * @return
     */
    public ListNode deleteNode(ListNode head, ListNode nodeToDelete) {
        //当head为空,或待删除节点为空
        if (head == null || nodeToDelete == null)
        {
            return null;
        }
        //删除非尾节点
        if (nodeToDelete.next != null)
        {
            ListNode nextNode = nodeToDelete.next;
            nodeToDelete.val = nextNode.val;
            nodeToDelete.next = nextNode.next;
        }
        //nodeToDelete即head,没有next,即只有头节点的特殊链表
        else if (nodeToDelete == head)
        {
            head = null;
        }
        //删除尾节点
        else
        {
            ListNode pnode = head;
            while(pnode.next != nodeToDelete)
            {
                pnode = pnode.next;
            }
            pnode.next = null;
        }
        return head;
    }

    /**
     * 删除指定值的节点
     * @param head
     * @param value
     * @return
     */
    public ListNode deleteNode(ListNode head, int value){
        if (head == null)
        {
            return null;
        }

        //寻找该节点
        ListNode pnode = head;
        while(pnode != null && pnode.val != value)
        {
            pnode = pnode.next;
        }

        //没找到对应值的节点
        if (pnode == null)
        {
            return null;
        }else
        {
            if (pnode.next != null)         //非尾节点
            {
                ListNode nextNode = pnode.next;
                pnode.val = nextNode.val;
                pnode.next = nextNode.next;
            }
            else if (pnode == head)          //是头节点,也是尾节点
            {
                head = null;
            }
            else                             //删除尾节点的情况
            {
                ListNode preNode = head;
                while(preNode.next != pnode)
                {
                    preNode = preNode.next;
                }
                preNode.next = null;
            }

        }
        return head;
    }

    public void printList(ListNode head)
    {
        if (head == null)
        {
            return;
        }
        ListNode pnode = head;
        while(pnode != null)
        {
            System.out.print(pnode.val + " ");
            pnode = pnode.next;
        }
        System.out.println();
    }
}

测试部分代码

package q18_01;

public class TestApp {
    public static void main(String[] args) {
        ListNode head = new ListNode(5);
        head.next = new ListNode(4);
        head.next.next = new ListNode(3);
        head.next.next.next = new ListNode(2);
        Solution s = new Solution();
        s.printList(head);

        s.deleteNode(head,3);

        ListNode temp = head;
        s.deleteNode(head, temp);
        s.printList(head);
    }
}

运行结果截图

在这里插入图片描述

LeetCode运行截图

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值