题目:删除链表中等于给定值 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 输出:[]
思路:本题属于链表中的基础题目。但也要注意一个细节。
删除链表节点的方式是将该节点的前一个节点的指针直接指向该节点的下个节点,并del该节点。所以头节点就不好删除。可以有两张方式,第一种是判断head为指定val时,就将head=head->next,其余元素仍用前面的方式删除,但这会造成处理头节点与处理其余节点是两个逻辑。因此我们可以引入一个虚拟的头节点dummyhead,dummyhead->next=head,这样就可以用同一个逻辑处理所有的节点。但需要注意的是最后返回结果时,返回的是dummyhead->next。
因为在C++中没有内存回收的机制。因此在用C++时,我们删除节点需要手动的del掉该节点,以免占用不必要的内存,养成良好的习惯。
题解(不构造虚拟头节点版):
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
while(head != NULL && head->val == val){ //单独处理头节点
ListNode* temp = head;
head = head->next;
delete temp;
}
ListNode* cur = head;
while(cur != NULL && cur->next != NULL){ //处理非头结点
if(cur->next->val == val){
ListNode* temp = cur->next;
cur ->next = temp->next;
delete temp;
}
else{
cur = cur->next;
}
}
return head;
}
};
题解(构造一个虚拟头节点版):(个人更喜欢这个方法!)
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(0); //构造一个虚拟头节点
dummyHead->next = head;
ListNode* cur = dummyHead;
while (cur->next != NULL) {
if(cur->next->val == val){
ListNode* temp = cur -> next; //定义一个头节点用来保存删除的节点
cur->next = temp->next;
delete temp; //删除节点释放空间
}
else{
cur = cur->next;
}
}
head = dummyHead->next;
delete dummyHead;
return head;
}
};