给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
方法一:迭代
/**
* 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) {
//如果链表的头节点为空直接返回head
if(head == nullptr){
return head;
}
ListNode* dummy = new ListNode(0); //虚拟节点dummy,方便返回新的链表
dummy->next = head; //令dummy的next指向head
ListNode* cur = head; //cur表示当前要判断的节点
ListNode* pre = dummy; //pre表示cur的前一个节点的位置
//while循环结束的条件是cur为空,即cur遍历到了链表的最后
while(cur != nullptr){
//如果当前cur节点的值与给定的val相等,那么就令pre->next = cur->next;即跳过cur这个节点
//注意此种情况不要移动pre的位置,因为我们难以保证当前cur->next是否是我们的目标值
if(cur->val == val){
pre->next = cur->next;
}
//如果当前cur节点的值与给定的val相等,pre、cur依次向前移动。
else{
pre = cur;
}
cur = cur->next;
}
return dummy->next;
}
//时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表一次。
//空间复杂度:O(1)。
};
方法二:递归
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//递归结束的条件就是当前进行递归的head为空
if(head == nullptr){
return nullptr;
}
//继续向下递归
head->next = removeElements(head->next,val);
//如果当前递归的head的值为目标值的话,我们就返回head->next,否则直接返回head
return head->val == val ? head->next : head;
}
//时间复杂度:O(n),其中 n 是链表的长度。递归过程中需要遍历链表一次。
//空间复杂度:O(n),其中 n 是链表的长度。空间复杂度主要取决于递归调用栈,最多不会超过 n 层。
};