当前位置:网站首页>【C语言刷题】Leetcode203——移除链表元素
【C语言刷题】Leetcode203——移除链表元素
2022-08-02 18:32:00 【桦秋静】
Leetcode203——移除链表元素
题目描述
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
链接:Leetcode203
示例
示例 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
核心代码模式
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */
struct ListNode* removeElements(struct ListNode* head, int val)
{
}
思路分析与代码实现
1.前后指针原地修改法
要删掉值为val的结点,那我们就遍历链表,遇到符合条件的结点就删掉。毕竟是要删掉结点,那就设置两个指针prev和cur一前一后。cur不为NULL就一直找下去,找到要删除结点时,要注意一下是不是头结点,要是头结点的话就就是头删了,先把cur下一个结点地址给头指针head,释放掉cur位置的结点,再把head值给cur让它指向下一个结点;若不是头结点,那就先把cur下一个结点地址给prev的next指针,让prev指向cur下一个结点,释放掉cur位置的结点,再把prev下一个结点的地址给cur,让它指向下一个结点。没找到要删除的结点的话就继续找下去。
代码实现
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode* prev = head;
struct ListNode* cur = head;
while(cur)
{
if(cur->val == val)
{
if(cur == head)
{
head = cur->next;
free(cur);
cur = head;
}
else
{
prev->next = cur->next;
free(cur);
cur = prev->next;
}
}
else
{
prev = cur;
cur = cur->next;
}
}
return head;
}
2.新链表尾插法
可不可以新建一个链表,定义新的头指针为newHead,然后就把值不等于val的结点放到新链表去,等于val的结点我们把它释放掉,所以我们要一个指针来遍历链表,定义cur指针。这里把值不等于val的结点放到新链表用的是尾插,那好了,尾插要是还要来个指针一个一个去找前一结点可太麻烦了,不妨定义一个尾指针tail用来指向新链表的尾部,这样尾插就方便多了。要注意有个坑,尾插到最后要记得把新链表最后一个结点的next指针给置为NULL。
代码实现
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode* cur = head;
struct ListNode* newHead = NULL;
struct ListNode* tail = NULL;
while(cur)
{
if(cur->val != val)
{
if(tail == NULL)
{
newHead = cur;
tail = cur;
}
else
{
tail->next = cur;
tail = cur;
}
cur = cur->next;
}
else
{
struct ListNode* del = cur;
cur = cur->next;
free(del);
}
}
if(tail)
tail->next = NULL;
return newHead;
}
试试带头链表
我们可以试试看用带头链表,头指的就是哨兵结点,不是用来存放有效数值的,而是用作辅助结点的。用哨兵结点在这有什么用呢?你想啊,之前不用它时是不是还要判断一下tail是不是NULL,但是用哨兵结点后tail至少是指向哨兵结点的,不会为NULL,是不是就省了点事?这里的哨兵结点我们命名为guard。
代码实现
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode* cur = head;
struct ListNode* guard = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* tail = guard;
while(cur)
{
if(cur->val != val)
{
tail->next = cur;
tail = cur;
cur = cur->next;
}
else
{
struct ListNode* del = cur;
cur = cur->next;
free(del);
}
}
tail->next = NULL;
head = guard->next;
free(guard);
return head;
}
边栏推荐
猜你喜欢
随机推荐
为何国内年轻人都抢购iPhone,因为它更实惠也更亲民
如何构建准实时数仓?
Openharmony - 基于ArkUI(TS)开发颜色选择器
千万级别的表分页查询非常慢,怎么办?
洛谷P5094 MooFest G 加强版
如何减轻企业账户被劫持的攻击?
千万级QPS下服务如何才能平滑启动
Boyun Selected as Gartner China DevOps Representative Vendor
[Dynamic Programming Special Training] Basics
洛谷P1966 火柴排队
Electronic Industry Inventory Management Pain Points and WMS Warehouse Management System Solutions
中职网络安全竞赛之应用服务漏洞扫描与利用
危及安全的常见物联网攻击有哪些?
记一次 .NET 某工控自动化控制系统 卡死分析
My recursive never burst stack
C#里如何简单的校验时间格式
针对时间的功能测试点,这里给你总结全面了
去年,一道蚂蚁金服笔试题,还行,中等难度
What skills are the most practical for college students in communications?
监控易火星版即将亮相:分布式运维帮助TOP3000大企业跨越管理鸿沟