本文已参与「新人创作礼」活动,一起开启掘金创作之路
前言
- 本系列主要讲解链表的经典题
注:划重点!!必考~
删除链表中等于给定值 val 的所有节点
力扣链接:203. 移除链表元素
给你一个链表的头节点
head和一个整数val,请你删除链表中所有满足Node.val == val的节点,并返回 新的头节点
- 示例:
- 提示:
- 列表中的节点数目在范围
[0, 104]内1 <= Node.val <= 500 <= val <= 50
- 解题思路:
- 这里我们选择使用尾插法,遍历链表把不是val的节点给尾插到一个新的链表上
- 这里对于在第一次尾插时(作为头节点)的特殊情况,我们选择创建带哨兵卫的头节点
注:创建带哨兵卫的头节点,在结束时记得释放(规范性)
- 参考代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
//写一个哨兵卫头节点
struct ListNode*phead=malloc(sizeof(struct ListNode));
phead->next=NULL;
//创建两个当前寻址指针
struct ListNode*cur1=head;
struct ListNode*cur2=phead;
while(cur1)//当cur1为NULL,则遍历链表完毕
{
if(cur1->val!=val)//不为删除值则接在有哨兵卫的链表后
{
cur2->next=cur1;
//cur2指在链表尾端
cur2=cur2->next;
}
//找到下一个地址
cur1=cur1->next;
}
//遍历完将尾端置空
cur2->next=NULL;
//保存哨兵后一个地址
struct ListNode*plist=phead->next;
//释放哨兵
free(phead);
return plist;
}
- 结果:
反转链表
- 题目描述:
给你单链表的头节点
head,请你反转链表,并返回反转后的链表
- 示例:
编辑
- 提示:
- 链表中节点的数目范围是
[0, 5000]-5000 <= Node.val <= 5000
- 解题思路:
这里我们采用三指针进行反转链表:
- 指针cur进行遍历链表
- 指针next记录cur的下一个指针,防止反转时下一个节点地址丢失
- 指针prev用来记录cur后指针,以便构建反转后的节点关系
注:需要处理好首节点节点之间的更替关系
- 参考代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* prev=NULL,*cur=head,*next;
while(cur)//cur为NULL时遍历链表结束
{
//保存下一个节点地址
next=cur->next;
//反转链接方向
cur->next=prev;
//更新后指向结点位置
prev=cur;
//更新指向当前节点位置
cur=next;
}
return prev;
}
- 结果: