【链表第六篇】leetcode203:移除链表元素(本质:链表删除指定值的节点,方案:用虚拟头结点,将特殊的头节点一般化处理)

210 阅读2分钟

基础题目:和链表第二篇第四节“单链表删去data为x的结点”

第203题:移除链表元素
题意:删除链表中等于给定值 val 的所有节点。

如果使用C/C++编程语言的话,不要忘了还要从内存中删除的节点,delete(节点)
如果使用java ,python的话就不用手动管理内存了。

还要说明一下,就算使用C++来做leetcode,如果移除一个节点之后,没有手动在内存中删除这个节点,leetcode依然也是可以通过的,只不过,内存使用的空间大一些而已,但建议依然要养生手动清理内存的习惯。

这种情况下的移除操作,就是让节点next指针直接指向下下一个节点就可以了

设置一个虚拟头结点在进行移除节点操作:

Java版本代码如下:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode first=new ListNode(0);
        first.next = head;
        ListNode pre = first;
        while(pre.next != null){  // 这样才能保证pre.next.next中,pre.next不为null,至于pre.next.next为null,没关系
            if(pre.next.val == val){
                pre.next = pre.next.next;  //跳过后一个,直接移动到第三个  
            }else{
                pre=pre.next;  // 移动到第二个
            }
        }
        return first.next;   // 一定不要把first输出了,要从first后面这个开始输出
        // 这里不能return head;下面解释
    }
}

这里必须 return first.next; 不能 return head; 为什么呢?如果 return head; 看一组输入输出,如下:

输入
[1,2,6,3,4,5,6] 6
输出
[1,2,3,4,5]
预期结果
[1,2,3,4,5]

输入
[1,6,2,6,3,4,5,6] 6
输出
[1,2,3,4,5]
预期结果
[1,2,3,4,5]

这是没问题的,但是,如果输入

输入
[6,1,2,6,3,4,5,6] 6
输出
[6,1,2,3,4,5]
预期结果
[1,2,3,4,5]

如果输入

输入
[6,6,1,2,6,3,4,5,6] 6
输出
[6,6,1,2,3,4,5]
预期结果
[1,2,3,4,5]

理由很简单,画一个图就清楚了,如下:

在这里插入图片描述

拿着这段代码去调试idea上就好了(其实leetcode上面也可以调试,主要是vip比较贵),如下

public class Solution2 {

    public static void main(String[] args) {
        int[] arrty = {1,6,2,6,3,4,5,6};
        ListNode first = new ListNode();
        ListNode r = first;
        for (int i = 0; i < arrty.length; i++) {
            ListNode node = new ListNode();
            node.val = arrty[i];
            r.next = node;
            r = node;
        }
        r.next = null;

        ListNode res = removeElements(first.next, 6);

        ListNode p = res;
        while (p != null) {
            System.out.print(p.val+" ");
            p = p.next;
        }
    }

    public static ListNode removeElements(ListNode head, int val) {
        ListNode first = new ListNode(0);
        first.next = head;
        ListNode pre = first;
        while (pre.next != null) {
            if (pre.next.val == val) {
                pre.next = pre.next.next;
            } else {
                pre = pre.next;
            }
        }
        return head;
    }
}


class ListNode {
    int val;
    ListNode next;

    ListNode() {
    }

    ListNode(int val) {
        this.val = val;
    }

    ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

这不是值传递和引用传递的问题