LeetCode Java链表203:移除链表元素

版权声明:转载请随意! https://blog.csdn.net/qq_41723615/article/details/89251325

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

示例:

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

提供的类:

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

思路1:不使用虚拟头结点,找到要删除的那个节点的前一个节点,考虑特殊情况:要删除的节点可能为头节点。

class Solution {

    public ListNode removeElements(ListNode head, int val) {
        //如果头节点不为空,且头结点是我们要删除的节点
        //用while表明下一个新的头结点可能也是要删除的节点
        while(head != null && head.val == val){
            //定义delNode等于待删除的头结点
            ListNode delNode = head;
            //将头结点的下一个节点换到头结点的位置上
            head = head.next;
            //令要删除的节点的指向为null,此时便删除一个节点
            delNode.next = null;
        }
        //如果整个链表都为要删除的节点,则直接在这里令头结点为空
        if(head == null) {
            //返回头节点
            return null;
        }
        //如果不是头结点,则需要声明一个指针,从头位置开始
        //此时的head,仅是表达位置的意思
        ListNode prev = head;
        //从头结点位置开始进行判断是否有下一个节点
        while(prev.next != null){
            //如果下一个节点的值等于要删除的值
            if(prev.next.val == val) {
                ListNode delNode = prev.next;
                prev.next = delNode.next;
                delNode.next = null;
            }else {
                //否则继续下一节点进行判断
                prev = prev.next;
            }
        }
        //返回一个新的head,方便下一次判断
        return head;
    }
}

对思路1进行简化:

class Solution {

    public ListNode removeElements(ListNode head, int val) {

        while(head != null && head.val == val) {
            //位置替换
            head = head.next;
        }

        if(head == null) {
            return head;
        }
        ListNode prev = head;
        while(prev.next != null){
            if(prev.next.val == val) {
                //位置替换
                prev.next = prev.next.next;
            }else{
                prev = prev.next;
            }
        }

        return head;
    }
}

思路2:使用虚拟头结点

class Solution {

    public ListNode removeElements(ListNode head, int val) {
        //虚拟头结点不需要传进去什么值,所以传进去不存在的-1位置
        ListNode dummyHead = new ListNode(-1);
        //虚拟头结点的下一个位置0即为头结点
        dummyHead.next = head;
        //设置指针从虚拟头节点开始,及头结点的前一个位置
        ListNode prev = dummyHead;
        //指针的下一个元素不为空
        while(prev.next != null){
            //如果该元素为要删除的元素
            if(prev.next.val == val) {
                //将该节点的下一个节点替换当前的节点
                prev.next = prev.next.next;
            }else{
                //否则从下一个节点重新进行判断
                prev = prev.next;
            }
        }
        //返回虚拟头结点的下一个节点
        return dummyHead.next;
    }
}

思路3:利用链表的天然递归性质。

class Solution {

    public ListNode removeElements(ListNode head, int val) {
        if(head == null) {
            return null;
        }
        //定义链表等于删除后的链表,递归
        ListNode res = removeElements(head.next, val);
        if(head.val == val) {
            return res;
        }else{
            //接上删除后的链表
            head.next = res;
            return head;
        }
    }
}

简化:

class Solution {

    public ListNode removeElements(ListNode head, int val) {
        if(head == null) {
            return null;
        }
        //直接将删除后的结果存在head.next中
        head.next = removeElements(head.next, val);
        if(head.val == val) {
            return head.next;
        }else{
            //否则返回head
            return head;
        }
    }
}

再简化:

class Solution {

    public ListNode removeElements(ListNode head, int val) {

        if(head == null) {
            return head;
        }
        head.next = removeElements(head.next, val);
        return head.val == val ? head.next : head;
    }

猜你喜欢

转载自blog.csdn.net/qq_41723615/article/details/89251325