题目描述
给你一个链表的头节点
head
和一个整数val
,删除链表中所有满足Node.val==val
的节点,并返回新的头节点。
思路
C++版:
头节点为要删除的节点时,把头节点往后移一位,同时手动删除该节点的内存空间。
非头节点为要删除的节点时,把该节点的前一位节点的next
指向下下个节点,同时手动删除该节点的内存空间。
方法
方法一
直接使用原来的链表进行移除操作。
这种方法需要单独写一段逻辑来移除头节点。
代码:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
//删除头节点
//用while来防止删除当前头节点后新头节点也需要删除的情况
while (head != NULL && head->val == val) {
ListNode* tmp = head;//定义一个临时指针用来保存头节点
head = head->next;//把头节点往后移一位
delete tmp;//手动删除已经移除节点的内存
}
//删除非头节点
ListNode* cur = head;//定义一个当前指针,最初指向头节点
while (cur != NULL && cur->next != NULL) {
//如果当前节点的下一个节点是要删除的节点
if (cur->next->val == val) {
ListNode* tmp = cur->next;//定义一个临时指针来保存要删除的节点
cur->next = cur->next->next;//改变当前节点的指针域,指向下下个节点
delete tmp;//手动删除要移除节点的内存空间
} else {
//当前节点的下一个节点不是要删除的节点
cur = cur->next;//移动当前指针到下一个节点
}
}
return head;
}
};
时间复杂度:O(n);
空间复杂度:O(1);
方法二
设置一个虚拟头节点,再进行移除节点的操作。
这样就可以对原链表用统一的方法进行元素移除了。
代码:
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* tmp = cur->next;//定义一个临时节点来存储要删除的节点
cur->next = cur->next->next;//删除节点,将当前节点的指针域指向下下个节点
delete tmp;//手动删除要删除节点的内存空间
} else {
//当前节点的下一个节点不是要删除的节点
cur = cur->next;//把当前节点指针移动到下一个节点
}
}
//删除操作结束之后
head = dummyHead->next;//把头节点指向虚拟头节点的下一个节点(真正的头节点)
delete dummyHead;//删除虚拟头节点
return head;
}
};
时间复杂度:O(n);
空间复杂度:O(1);