从今天开始争取做到leetcode每日一更!
话不多说,启动!
我们的结构是题目,加上实现分析,然后是代码实现
题目:
给你一个链表的头节点 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.正常情况:
遍历一遍列表,每找到值相等的时候删除节点,返回头节点
所以这里首先想到的就是自己定义一个哨兵位头节点,这样就不用陷入到讨论空各种情况,但是随之而来的是增加了空间复杂度。
法一:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
dummyHead->next = head; // 将虚拟头结点指向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;
}
};
这里大致分为三步走,第一步定义一个dummynode,第二部进行循环判断是否元素相同,第三步删除返回。
法二:
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
// 删除头结点
while (head != NULL && head->val == val) { // 注意这里不是if
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;
}
};
如果不用头节点的话,就应该讨论删除的是否是头节点的情况
所以这里需要注意的是,一开始不能用if来判断条件,必须要用while,是为了应对连续头节点的值等于val
的情况。
假设有一个链表如下:
head -> 7 -> 7 -> 7 -> 2 -> 3
如果用了if来判断,if
只会检查一次head
的值。当链表的第一个节点的值等于val
时,它会删除这个节点,然后把head
移动到下一个节点。但是if
不会继续检查新的head
的值。如果新的head
仍然等于val
,这个值就不会被删除。删除结果如下:head -> 7 -> 7 -> 2 -> 3,不满足删除所有的7