0%

203. Remove Linked List Elements

O(n) 朴素解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode dummy_head(0), *prev = &dummy_head;
prev->next = head;
for (auto curr = head; curr; curr = curr->next) {
if (curr->val == val) {
prev->next = curr->next;
} else {
prev = curr;
}
}
return dummy_head.next;
}
};

O(n)二级指针法
一般一个节点分两部分,数据和next指针,各自有不同的地址(占用不同的内存空间),我们要做的是改变要删除的节点的前驱节点的next指针的值,如果当前节点不是要删除的目标节点,我们取next指针的地址保存起来,即list = &(*list)->next;,下次循环的时候,我们是站在前驱节点的位置来检查前驱节点的后继节点是不是要被删除的目标节点,如果是的话,直接修改这个『next』指针值,即*list = (*list)->next;,相当于node->next = node->next->next;,其中node->next是要被删除的目标节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode **list = &head;

while (*list)
{
if ((*list)->val == val)
{
*list = (*list)->next; // 因为之前保存了前驱节点的next指针信息,所以可以直接修改前驱节点的next指针的值为当前节点的后继节点
} else {
list = &(*list)->next; // 保存的其实是当前节点的next指针信息,而不是下一个节点
}
}

return head;
}
};

O(n)递归解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if (!head) return nullptr;
head->next = removeElements(head->next, val);
return head->val == val ? head->next : head;
}
};