题目描述
题目来源:力扣(LeetCode)
题目链接:203. 移除链表元素
给你一个链表的头节点
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
输出: []
提示:
- 列表中的节点数目在范围
[0, 104]内 1 <= Node.val <= 500 <= val <= 50
解题方法一:迭代
思路
建立一个包含哑节点的单链表,记录其尾节点。
- 因为原链表头节点可能被删除,为了方便指针操作需要哑节点。 遍历原链表,当需要保留节点时,通过尾插法插入到新链表;当需要删除节点时,通过指针变换移除该节点,并释放内存。
代码
/**
* 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) {
// dummy 为哑节点,tail 为尾节点
auto dummy = new ListNode(0, head), tail = dummy;
// 还存在待处理节点
while(tail->next) {
if(tail->next->val == val) {
// tmp 为待删除节点
auto tmp = tail->next;
// 从链表移除 tmp
tail->next = tmp->next;
// 释放内存
delete tmp;
}else {
// 往右移动
tail = tail->next;
}
}
// 更新head
head = dummy->next;
// 释放内存
delete dummy;
return head;
}
};
解题方法二:递归
思路
removeElements 能够删除以 head 为头节点的单链表中的等于 val 的节点,并且返回新的头节点。那么递归出口为 head 是空指针。
代码
/**
* 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) {
// 递归出口
if(!head) {
return head;
}
// 递归
head->next = removeElements(head->next, val);
// 需要删除当前节点
if(head->val == val) {
auto tmp = head;
// 更新 head
head = head->next;
// 释放内存
delete tmp;
}
return head;
}
};