[LeetCode]day9 203.移除链表元素

203. 移除链表元素 - 力扣(LeetCode)

题目描述

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == 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
输出:[]

提示:

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

解题

数据结构里早就学过怎么删除链表元素了,原本以为可以手拿把掐,没想到一写就出各种细节上的问题!!

这道题唯一的难点就是在于怎么处理返回这个头结点,题目中的这个头结点是带有数据的,而不是指向第一个有效结点的结点 ,所以是有可能为待删除元素的,而删除这个头结点和删除其他节点的操作有所不同。

解法一:使用原来的链表来进行移除节点操作

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
 
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode*p;
        if(head==NULL)return NULL;
        //处理头结点为待删结点的情况
        while(head != nullptr&&head->val==val){ //注意这个条件判断的前后顺序
           p=head;
           head=head->next;
           delete p;  //c/c++要记得释放内存
        }
        p=head; 
        while(p&&p->next){ //要这两个都不为空才行
            if(p->next->val==val){
                ListNode*q=p->next;
                p->next=p->next->next;
                delete q;
            }else{
                p=p->next; //这里不是每次都要执行的
            }
        
        }
        return head;
    }
};

有几个点特别容易错..

1.while(head != nullptr&&head->val==val) 两个判断的前后顺序千万不能反..一定要先判断是否为空,再判断是否等于val. 因为当head为空时先判断head->val==val会造成访问空指针的错误!

2.使用c/c++要记得释放内存!

3.while(p&&p->next) 两个条件都要满足 因为后面的删除操作会访问p->next;

4.p=p->next不是每次循环都要执行的,只有不删除元素时才执行,如果删除了元素就不执行(可以画个图进行理解)


解法二:引入虚拟头结点

如果我们引入一个虚拟的头结点,那删除头结点和其他结点的操作就统一了。

cpp 复制代码
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode*dummy=new ListNode(0),*q;
        dummy->next=head;
        q=dummy;
        while(q&&q->next){
            if(q->next->val==val){
                ListNode*p=q->next;
                q->next=q->next->next;
                delete p;
            }else{
                q=q->next;
            }
        }
        return dummy->next;
    }
};

这里有一个易错点就是要记得为虚拟头结点申请空间

相关推荐
张欣-男16 分钟前
3分钟理解线性代数
线性代数·算法
白狐_79820 分钟前
408 数据结构|外部排序优化:怎么减少时间开销
数据结构·算法
小白说大模型20 分钟前
Hermes 全配置指南:从裸版到 AI Agent 天花板
大数据·人工智能·学习·算法·机器学习·数据挖掘
a1879272183130 分钟前
【算法】动态规划入门:从打家劫舍到状态设计的三堂课
算法·leetcode·动态规划·dp·回溯·暴力
淡海水10 小时前
07-04-并发-ConcurrentBag-T-工作窃取WorkStealing算法
开发语言·算法·c#·bag·concurrent·workstealing
leobertlan10 小时前
好玩系列:训练一个神经网络模型指导小孩玩游戏2-大局观教练
算法
Tisfy11 小时前
LeetCode 3876.构造奇偶一致的数组 II:三种情况分类讨论(其实还是脑筋急转弯)
算法·leetcode·题解·脑筋急转弯
乐迪信息12 小时前
智慧港口船舶AI算法实现在线状态监测
大数据·人工智能·深度学习·算法·计算机视觉
kiracrimson13 小时前
从缓存的角度看链表与线性表的差异
数据结构·链表·缓存
木井巳14 小时前
【BFS/DFS 解决 FloodFill 算法】太平洋大西洋水流问题
java·算法·leetcode·深度优先·广度优先·宽度优先·推荐算法