每日一题:移除链表元素

321 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

题目链接

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

**实例 1: image.png

输入: 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
输出: []

 

提示:

  • 列表中的节点数目在范围 [0, 104] 内
  • 1 <= Node.val <= 50
  • 0 <= val <= 50

解题思路:

这里以 链表 3,2,1,3,1举例,移除 1

image.png

移除后的链表

image.png

要注意的是: 如果是用C和C++来做题的人,不要忘了还要从内存里删除这两个移除的节点,如果用的是JAVA,就需要手动管理内存

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

通过上面的图能看出,移除元素的操作,就是让节点next指针直接指向下下一个节点

因为单链表的特殊性,指针只能指向下一个节点,那么这里就会有一个问题,如果删除的是头节点该怎么办呢?

这里可以用链表操作的两种方式

  1. 直接使用原来的链表进行删除操作
  2. 设置一个虚节点,再进行删除操作

这里我们先来看第一种方式:直接使用原来的数组进行删除操作

image.png

移除头节点和移除其他节点的操作是不一样的,因为链表的其他节点都是需要通过前一个节点来移除元素的,而头节点没有前一个节点

我们只需要将头节点向后移一位,就完成了移除头节点的这个操作

image.png

这里别忘了将移除的节点从内存中删除

这里可以发现,在单链表里移除头节点和移除其他节点的操作还是不一样的,我们在写代码的时候,需要单独写一个逻辑处理移除头节点的情况

写完第一个方式,我们再来看第二种方式:设置一个虚节点,再进行删除操作

我们来看看添加一个虚节点后,如何移除节点

这里还是用链表 1,2,6,3,5 移除1 进行操作

image.png

可以看到,添加了虚节点后,删除的操作就跟删除其他节点的操作一样了

最后在返回头节点时,要 return head.next,这才是新的头节点

代码: (Java实现)

不添虚节点

public ListNode removeElements(ListNode head, int val) { 
        //判断删除的节点是否为头节点,如果是,就把头节点移动到下一位
        if (head != null && head.val == val) {
            head = head.next;
        }

        if (head == null) {
            return head;
        }

        ListNode per = head;
        ListNode cur = head.next;
        while (cur != null) {
            if (cur.val == val) {
                per.next = cur.next;
            }else {
                per = cur;
            }
            cur = cur.next;
        }

        return head;
    }
复杂度分析:
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
提交结果:

image.png

添加虚节点

public ListNode removeElements(ListNode head, int val) {
    if (head == null) {
        return null;
    }

    //创建虚节点
    ListNode one_head = new ListNode(-1,head);

    //创建虚节点
    ListNode per = one_head;

    //实际头节点
    ListNode cur = head;

    while (cur != null) {
        if (cur.val == val) {
            per.next = cur.next;
        }else {
            per = cur;
        }
        cur = cur.next;
    }

    return one_head.next;
}
复杂度分析:
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
提交结果:

image.png