【LeetCode_203】移除链表元素
刷爆LeetCode系列
- LeetCode第203题:
- github地址
- 前言
- 题目描述
- 题目与思路分析
- 思路一
- 思路二
- 代码实现
- 思路一代码实现
- 思路二代码实现
LeetCode第203题:
github地址
有梦想的电信狗
前言
本文用C++
解答LeetCode
第203
题
题目描述
题目链接:https://leetcode-cn.com/problems/remove-linked-list-elements/description/
题目与思路分析
目标分析:
- 将链表中
Node.val == val
的结点删除 - 返回新的链表的头结点
- 提高要求:时间复杂度为
O(n)
,空间复杂度为O(1)
思路一
思路:遍历一遍删除,边遍历边删除
curNode
:用于扫描结点,从头结点开始依次扫描所有结点curPrev
:删除节点后需要更改链接关系,因此curPrev
用于记录被删除结点的前一个结点
操作:删除结点分为删除头结点和删除其他结点
curNode->val != val
时,说明:curNode
无需被删除,curNode
和curPrev
整体向后移动。curPrev = curNode;
curNode = curNode->next;
curNode->val == val
时,说明:curNode
要删除,分为头删和其他删两种情况- 头删:需要删结点并改head
curNode
向后移动:curNode = curNode->next;
- 释放头结点:
delete head;
- 再更新头结点:
head = curNode;
- 删除非头结点:只需删除结点
ListNode* delNode = curNode;
curNode = curNode->next;
delete delNode;
curPrev->next = curNode;
- 头删:需要删结点并改head
- 最终返回
return head;
思路二
- 借鉴删除数组中指定元素的思路:
思路:创建一个newHead,初始时newHead == nullptr,将不等于val的结点,尾插到新链表中
curNode
:用于扫描结点,从头结点开始依次扫描所有结点newHead
:移除元素后新链表的头结点
操作:删除curNode->val == val
的结点,将curNode->val != val
的结点尾插到newHead
链表中
-
curNode->val != val
时,说明:curNode
需要被尾插到新链表-
第一次尾插时(
if(newHead == nullptr
)需要特殊处理:tailNode = newHead = curNode;
curNode = curNode->next;
-
其余结点的尾插,常规化处理:
tailNode->next = curNode;
tailNode = tailNode->next;
curNode = curNode->next;
-
-
curNode->val == val
时,说明:curNode
要被删除,执行删除结点的逻辑即可 -
链表最后的
tailNode
的next
指针需要置空,且链表为空时,tailNode
为空,要防止对空指针解引用 -
最终返回
return newHead;
代码实现
思路一代码实现
class Solution {
public:ListNode* removeElements(ListNode* head, int val) {ListNode* curNode = head;ListNode* curPrev = nullptr;while(curNode){if(curNode->val != val){curPrev = curNode;curNode = curNode->next;}else{// 值相等时分为头删和非头删// 1. 头删 需要删结点 并 改 headif(curNode == head){curNode = curNode->next;delete head;head = curNode;}// 2. 非头删,只需删结点 else{ListNode* delNode = curNode;curNode = curNode->next;delete delNode;curPrev->next = curNode;}}}return head;}
};
思路二代码实现
// 思路二,用删除数组中指定元素的方法
// 创建一个newHead, 将不是val的结点,尾插到新链表中
class Solution {
public:ListNode* removeElements(ListNode* head, int val) {ListNode* newHead = nullptr;ListNode* curNode = head;// 尾插,为了避免频繁找尾,记录尾结点ListNode* tailNode = nullptr;while(curNode) {if(curNode->val == val){ListNode* delNode = curNode;curNode = curNode->next;delete delNode;}else{// != val 的尾插到新链表// 第一次尾插需要特殊处理if(newHead == nullptr){tailNode = newHead = curNode;curNode = curNode->next;}else{tailNode->next = curNode;tailNode = tailNode->next;curNode = curNode->next;}}}// 链表为空时,tailNode 为空,防止对空指针解引用if(tailNode)tailNode->next = nullptr;return newHead;}
};
以上就是本文的所有内容了,如果觉得文章对你有帮助,欢迎 点赞⭐收藏 支持!如有疑问或建议,请在评论区留言交流,我们一起进步
分享到此结束啦
一键三连,好运连连!
你的每一次互动,都是对作者最大的鼓励!
征程尚未结束,让我们在广阔的世界里继续前行!
🚀