我们以 题讲知识
引入力扣的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
输出:[]
示例 3:
输入:head = [7,7,7,7], val = 7
输出:[]
第一种方法,我们分别讨论移除头节点和中间节点,因为我们移除节点原理是:比如1,2,3三个节点,移除2是通过1的指针指向3跳过2,但是移除1就是通过令2的指针等于1的,所以会发现头结点的移除不同于其他节点,所以我们需要分开来看
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
while(head!=NULL&&head->val==val){//这里用while,不用if,因为可能不止一个头节点符合条件,比如本题的第三种情况
head=head->next;
}
if(head==NULL){
return NULL;
}
struct ListNode* pre= head;
while(pre->next!=NULL){
if(pre->next->val==val){
pre->next=pre->next->next;
}
else{
pre=pre->next;
}
}
return head;}
};
第二种方法就是虚拟头节点,可以创造一个新的头节点,我们通常令虚拟头节点的值为-1,因为我们不用这个数,那么真正的头结点的移除方式和其他节点就一样了
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
struct ListNode* dummyHead = new ListNode(-1, head);
struct ListNode* temp = dummyHead;
while (temp->next != NULL) {
if (temp->next->val == val) {
temp->next = temp->next->next;
} else {
temp = temp->next;
}
}
return dummyHead->next;//注意输出的时候不是从虚拟头节点开始
}
};
第三种方法就是递归,这种方法较难理解,建议新手使用第二种方法,递归就是,先往下“递”
再往回“归”,递的时候,当发现节点为空时停止,开始往回归,判断是否节点满足条件,开始移除节点操作
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if (head == nullptr) {
return head;
}
head->next = removeElements(head->next, val);
return head->val == val ? head->next : head;
}
};