【数据结构与算法】Java链表与递归:移除链表元素

本文介绍了如何使用Java处理链表中删除指定元素的问题,提供了两种解决方案:一种是通过虚拟头节点简化操作,另一种是不使用虚拟头节点但需要考虑头节点的特殊情况。每种方法都避免了显式的节点释放,利用了内存自动回收。代码展示了解决此问题的清晰步骤。

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

Java链表与递归:移除链表元素

Java
https://leetcode-cn.com/problems/remove-linked-list-elements/solution/javalian-biao-yu-di-gui-yi-chu-lian-biao-264p/

解题思路

两种结题方式,使用虚拟头节点或者不使用。
使用虚拟头节点简单易理解,从虚拟头节点开始,一个一个地看下一个元素,是目标元素则改动当前节点next指针跳过一下,并且重新检查下一个节点(存在下两个及以上节点都应该删除的情况),不是目标元素就将下一个节点变为目标节点,直到下一个目标节点为空。最后返回的是虚拟头节点next指向的真实头节点。
不使用头节点要分两种状态考虑,一个是头节点就是要删除的目标节点,另外一个是非头节点是要删除的节点,两种处理方式不一样,首先进来检查头节点,如果是要删除的节点,直接将head指向头节点的下一个节点以跳过来删除,之后再次检查头节点(存在开头两个及以上都应该删除的情况),直到当前头节点不应该被删除或者链表被删空了,然后接下来才检查除开头节点之外的节点是否要删除。在检查之前,因为上次退出循环有两个条件,不知道是哪个条件导致循环退出的,所以需要判断一下链表是不是空了(即头结点为空),是则直接返回空,不是再类似使用虚拟头结点的方式将头结点之后的元素逐一判断或删除。

代码

class Solution {
    // 使用虚拟头结点解决
    public ListNode dummyHead(ListNode head, int val) {
        // 虚拟头节点
        ListNode dummyHead = new ListNode();
        dummyHead.next = head;
        
        ListNode cur = dummyHead;
        while (cur.next!=null){
            if(cur.next.val == val){
//                ListNode delNode = cur.next;
//                cur.next = cur.next.next;
//                delNode.next = null;
                // 内存自动回收,这样解决
                cur.next = cur.next.next;
            }else {
                cur = cur.next;
            }
        }
        // 返回头结点
        return dummyHead.next;
    }

    // 使用一般方法解决
    public ListNode normal(ListNode head, int val) {
        // 每次节点不能为空,可能删除一个就空了,下一个判断会空指针异常
        while (head != null && head.val == val) {
//                ListNode delNode = head;
//                head = delNode.next;
//                delNode.next = null;
            // 自动内存处理,直接跳过就好
            head = head.next;
        }

        // 考虑到所有元素在头结点被删除
        if (head == null) {
            return null;
        }

        for (ListNode cur = head; cur.next != null; ) {
            // 如果指针的下一个节点是要被删除的
            if (cur.next.val == val) {
//                    ListNode delNode = cur.next;
//                    cur.next = cur.next.next;
//                    delNode.next = null;
                // 内存自动回收,直接跳过
                cur.next = cur.next.next;
            } else {
                // 如果每次执行会跳过连续被删除的节点
                cur = cur.next;
            }
        }
        return head;
    }

    public ListNode removeElements(ListNode head, int val) {
        return dummyHead(head,val);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉米子禾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值