部分圖文參考於:程式碼隨想錄 - 203.移除連結串列元素。
C++程式設計中記得要手動釋放結點記憶體。
連結串列操作中,可以使用原連結串列來直接進行刪除操作,也可以設定一個虛擬頭結點再進行刪除操作。
1.題目連結
203.移除連結串列元素
2.思路
以連結串列 1 4 2 4 來舉例,移除元素4。
如果使用C,C++程式語言的話,不要忘了還要從記憶體中刪除這兩個移除的節點, 清理節點記憶體之後如圖:
在單連結串列中移除頭結點 和 移除其他節點的操作方式不一樣,需要單獨寫一段邏輯來處理移除頭結點的情況。
針對頭結點和非頭結點使用不同的刪除方式:
1.針對頭結點等於刪除值,將頭結點head指向下一個值不等於val的結點。
注:別忘將原頭結點從記憶體中刪掉。
2.針對非頭結點等於刪除值,使用cur指向頭結點,檢測cur->next所指向的結點的值是否等於val。如果相等,則將cur->next指向cur->next->next,即刪除結點;不相等,則將cur繼續向下一個結點移動。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
while (head && head->val == val) {
ListNode* temp = head;
head = head->next;
delete temp;
}
ListNode* cur = head;
while (cur && cur->next) {
if (cur->next->val == val) {
ListNode* temp = cur->next;
cur->next = cur->next->next;
delete temp;
}
else cur = cur->next;
}
return head;
}
};
● 時間複雜度:O(n)
● 空間複雜度:O(1)
2.2.解法2:使用虛擬頭結點
使用這種方式,不用再區分頭結點和非頭結點,原連結串列的所有節點就都可以按照統一的方式進行移除了。
來看看如何設定一個虛擬頭。依然還是在這個連結串列中,移除元素1。
這裡來給連結串列新增一個虛擬頭結點為新的頭結點,此時要移除這個舊頭結點元素1。
return 頭結點的時,return dummyNode->next;才是新的頭結點。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* cur = dummyHead;
while (cur->next) {
if (cur->next->val == val) {
ListNode* temp = cur->next;
cur->next = cur->next->next;
delete temp;
}
else cur = cur->next;
}
head = dummyHead->next;
delete dummyHead;
return head;
}
};
● 時間複雜度:O(n)
● 空間複雜度:O(1)