C/C++的定义链表节点方式,如下所示:
// 单链表
struct ListNode {
int val; // 节点上存储的元素
ListNode *next; // 指向下一个节点的指针
ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数
};
力扣:203.移除链表元素
题目:
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
删除节点的要点就是:要知道删除节点的前一个节点。此时才能够完成要删除节点的前后节点的链接。
删除节点问题的关键在于:要知道删除节点的前一个节点,首节点没有前一个节点,那么此时首节点的删除怎么办。
两种方法:
①:创建一个node节点,将此节点作为首节点,就只需要从第二个节点开始删除。每次要判断的节点是node->next,此时node就作为要删除节点的前一个节点。
②:直接将首节点删除(此时首节点满足条件(首节点的值是目标值)),直到首节点的值不是目标值。每次要判断的节点是 head->next,此时 head 就作为要删除节点的前一个节点。
个人更喜欢第二种
方法①代码:
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;
}
};
方法②代码:
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;
}
};