文章目录
前言
本专栏文章为《代码随想录》书籍的刷题题解以及读书笔记,如有侵权,立即删除。
一、题目
1、原题链接
2、题目描述
二、解题报告
1、思路分析
- 链表删除元素核心思路就是:找到要删除元素的前一个节点;将该节点直接指向待删除元素的后一个节点即可。
- 需要注意的是:头节点的删除与其他节点的删除操作可能不同,即删除头节点只要将头节点后移一位,将原来的头节点内存空间释放即可。
- 为了统一操作,可以引入虚拟头节点 :在原链表头节点之前添加一个节点作为虚拟头节点(虚拟头节点指向原链表的头节点 ),不作为原链表的元素,只是为了方便,统一链表节点的删除操作。
- 需要注意的一点是:不能直接使用头节点(虚拟头节点)来作为遍历节点 ,需要创建一个临时新的节点来替代头节点进行链表遍历,因为最终需要返回链表,所以头节点(虚拟头节点)的指针域不能被修改(返回的就是头节点,根据头节点来找到删除后的结果链表)。
2、代码详解
cpp
/**
* 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) {
ListNode* fakehead = new ListNode(0, head); // 虚拟头节点 指向原链表的头结点
ListNode* cur = fakehead; // cur充当遍历指针
while(cur->next != NULL) { // 因为后续要取cur->next->val,所以条件为非空,避免空指针操作
if (cur->next->val == val) { //删除操作
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
}
else { //遍历到下一个节点
cur = cur->next;
}
}
//返回真正的头节点,注意不能直接返回head,因为head可能已被删除
head = fakehead->next;
delete fakehead;
return head;
}
};
三、知识风暴
- 使用虚拟头节点统一删除链表节点的操作;
ListNode* node = new ListNode();(好久不写C++代码了,都忘了创建对象需要new了)
