1.题目
https://leetcode.cn/problems/remove-linked-list-elements/description/
给你一个链表的头节点
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
- 代码模板
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* removeElements(struct ListNode* head, int val) { }
2.自解
算法:双指针一次遍历
不加思索写出以下代码
struct ListNode* removeElements(struct ListNode* head, int val)
{if (head==NULL)return NULL;struct ListNode* prev=NULL;struct ListNode* cur=head;while(cur){if (cur->val!=val){prev=cur;cur=cur->next;}else{prev->next=cur->next;free(cur);cur=prev->next;}}return head;
}
会发现报错(null pointer)
分析: 当头结点的需要删除时,执行if判断的else部分
else{prev->next=cur->next;free(cur);cur=prev->next;}
prev->next为NULL->next,这是非法的
因此需要先判断prev是否为NULL,如果为NULL则头删(注意:头删一定要移动头结点)
if (cur->val!=val){prev=cur;cur=cur->next;}else{if (prev==NULL){head=cur->next;free(cur);cur=head;}else{prev->next=cur->next;free(cur);cur=prev->next;}}
其他注意事项:特殊情况优先判断:是否为空链表
if (head==NULL)return NULL;
完整代码为:
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
struct ListNode* removeElements(struct ListNode* head, int val)
{if (head==NULL)return NULL;struct ListNode* prev=NULL;struct ListNode* cur=head;while(cur){if (cur->val!=val){prev=cur;cur=cur->next;}else{if (prev==NULL){head=cur->next;free(cur);cur=head;}else{prev->next=cur->next;free(cur);cur=prev->next;}}}return head;
}
提交结果:
3.其他解法
尾插算法,需要找尾,因此需要尾指针tail
不加思索写出以下代码
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
struct ListNode* removeElements(struct ListNode* head, int val)
{if (head==NULL)return NULL;struct ListNode* newhead=NULL;struct ListNode* tail=NULL;struct ListNode* cur=head;while(cur){if (cur->val!=val){if (tail==NULL){newhead=tail=cur;}else{tail->next=cur;tail=tail->next;}cur=cur->next;}else{struct ListNode* next=cur->next;free(cur);cur=next;}}return newhead;
}
添加对tail的判断,改成下面这样就行
else{struct ListNode* next=cur->next;free(cur);cur=next;}}if (tail)tail->next=NULL;return newhead;
}
完整代码为
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
struct ListNode* removeElements(struct ListNode* head, int val)
{struct ListNode* newhead=NULL;struct ListNode* tail=NULL;struct ListNode* cur=head;while(cur){if (cur->val!=val){if (tail==NULL){newhead=tail=cur;}else{tail->next=cur;tail=tail->next;}cur=cur->next;}else{struct ListNode* next=cur->next;free(cur);cur=next;}}if (tail)tail->next=NULL;return newhead;
}