刷题日记——移除链表元素

20 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情

203.移除链表元素

力扣题目链接(opens new window)

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

示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

示例 2:
输入:head = [], val = 1
输出:[]

示例 3:
输入:head = [7,7,7,7], val = 7
输出:[]

这道题刚上来我只会用c语言那种指针写法,用Java不知道该怎么写,所以先来学习下java关于链表的语法。

创建链表

public class ListNode {
    // 结点的值
    int val;

    // 下一个结点
    ListNode next;

    // 节点的构造函数(无参)
    public ListNode() {
    }

    // 节点的构造函数(有一个参数)
    public ListNode(int val) {
        this.val = val;
    }

    // 节点的构造函数(有两个参数)
    public ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

以及几种初始化链表节点的写法:

  1. 初始化一个空节点,没有赋值,指针指向为list (不推荐)

ListNode list = new ListNode();

  1. 初始化一个空节点,初始赋值为0,指针指向为list

ListNode list = new ListNode(0);

  1. 初始化一个空节点,初始赋值为0,并且list的下一个next指针指向head,指针指向为list

ListNode list = new ListNode(0,head);

  1. 定义一个空链表

ListNode list=null;

此外也学习了js的语法

class ListNode {
  val;
  next = null;
  constructor(value) {
    this.val = value;
    this.next = null;
  }
}

直接使用原来的链表进行删除

这种方法中要判断目标是是不是头结点,如果是头结点就要单独删除它,这是为什么呢

因为我们的删除方法是找到等于目标值的节点的上一个节点,然后让上一个节点的指针指向这个节点的下个节点,直接掠过这个目标节点。但是对于头结点来说他就是第一个节点,是没有上一个节点的,所以要用另一种方式删除。由此,我们就可以写出代码如下

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        while(head!=null && head.val==val){
            head=head.next;
        }
        ListNode cur=head;
        while(cur!=null && cur.next!=null){
            if(cur.next.val==val){
                cur.next=cur.next.next;
            }else{
                cur=cur.next;
            }
        }
        return head;
    }
}

设置虚拟节点

这种方法就是在头结点之前设置一个虚拟头结点,这样假如头结点等于目标值,我们也可以找到他的上一个节点,因此在这种方法中,大家就都是用一套统一的规则删除,一视同仁了。代码如下

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if(head==null) return null;
        ListNode dummy=new ListNode(-1,head);
        ListNode cur=dummy;
        while(cur!=null && cur.next!=null){
            if(cur.next.val==val){
                cur.next=cur.next.next;
            }else{
                cur=cur.next;
            }
        }
        return dummy.next;
    }
}

这里我都没有用pre指针,大家在写的时候也可以在设置一个pre指针,开始让pre指向dummy,让cur指向head,思路是一样的。