五 递归3 力扣203链表删除节点列题


LeetCode 203
203. 移除链表元素
难度:简单

题目:删除链表中等于给定值 val 的所有节点。

示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5

方法一:使用dummyHead并循环链表
class Solution {
    //解法一,使用dummyHead
    public ListNode removeElements(ListNode head, int val) {
        //方法一 循环链表,并设置dummyHead,如果改节点等于val,就将dummyHead指向下一个节点
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;

        ListNode prev = dummyHead;
        while (prev.next != null) {
            if (prev.next.val == val) {
                ListNode delNode = prev.next;
                prev.next = delNode.next;  //让prev跨国被del节点,prev已经相当于移动了
                delNode.next = null; //让被删除节点与链表断掉联系
            } else {
                prev = prev.next; //单纯移动pre向后一位  //这句话要用else包起来,不能直接放在if后面,因为if后面,因为上门已经移动了
            }
        }
        return dummyHead.next; //这里要返回要注意,因为有可能除了dummyHead,其他都被删除了
    }
}
方法二:循环链表,使用head
//解法二  直接使用head,需要在代码里对head做特殊处理
class Solution {
    public ListNode removeElements2(ListNode head, int val) {
        //先处理head 首先head不为空,且head==val,则删除head
//        if ( head.val == val && head != null) {
//            head = head.next;
//        }

        //!!!! 上面的if中的逻辑是循环的,所以把if改成while!!!!!
        while (head.val == val && head != null) {
            head = head.next;  //这个方法是简单写,因为leetcode里提交忽略了loitering object
        }

        //一路删下去,head都是val,在这里head约等于一个current指针
        if (head == null)
            return null;

        //有head,且head不等于val,head可以看作prev,然后一路判断下去
        ListNode prev = head;
        while (prev.next != null) {
            if (prev.next.val == val) {
                ListNode delNode = prev.next;
                prev.next = delNode.next;  //让prev跨国被del节点,prev已经相当于移动了
                delNode.next = null; //让被删除节点与链表断掉联系
            } else {
                prev = prev.next; //单纯移动pre向后一位  //这句话要用else包起来,不能直接放在if后面,因为if后面,因为上门已经移动了
            }
        }
        return head;
    }
}
方法三:使用递归

在这里插入图片描述

注意,用递归构造出上面的宏观计算方法
而且 红条条代表着一个 removeElements3 递归方法

class Solution {
//解法三  使用递归,链表的天然递归性
    public ListNode removeElements3(ListNode head, int val) {

        if (head == null) {
            return null;
        }
        //递归体写法一
//        ListNode res = removeElements3(head.next, val);
//        if (head.val == val) {
//            return res;
//        } else {
//            head.next = res;
//            return head;
//        }

        //另一种递归体写法:
//        head.next = removeElements3(head.next, val);
//        if (head.val == val) {
//            return head.next; //返回删除了头节点之后的部分,可以表达成
//        }else {
//            return head; //直接返回传入的参数,不做删除
//        }

        //另一种写法
        if (head.val == val) {
            return removeElements3(head.next, val);
        } else {
            head.next = removeElements3(head.next, val);
            return head;
        }

        //或者直接三目运算
//        head.next = removeElements3(head.next, val);
//        return head.val == val ? head.next : head;
    }
}
定义ListNode

该题是LeetCode上的,将使用LeetCode提供的ListNode类。
并提供一个ListNode的"this"对象,然后该对象后面接着一排链表

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

    //自己测试代码,需要调用solution中的removeElements(ListNode head, int val)
    //所以我们自己构造出 ListNode head!!!
    //新创建一个构造函数
    public ListNode (int[] arrs) {
        if (arrs == null || arrs.length == 0) {
            throw new IllegalArgumentException("The array can not be empty.");
        }

        //这个this 就是创建的链表的头节点!!!!
        this.val = arrs[0]; //对于ListNode来说,第一个元素就是head,而且要给val赋值!!! 接着把下面的元素接起来

        ListNode current = this; //!!!! 从第一个节点开始!!!!
        for (int i = 1; i < arrs.length ; i ++) {
            current.next = new ListNode(arrs[i]);
            current = current.next;
        }

    }

    //!!!以当前节点为头节点的链表信息字符串!!!!!!!!!
    @Override
    public String toString() {
        StringBuilder ret = new StringBuilder();
        ret.append("ListNode : head ");

        ListNode cur = this; //从当前节点开始循环
        while (cur != null) {
            ret.append( cur.val + "-> ");
            cur = cur.next;
        }
        ret.append("null");

        return ret.toString();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值