一、思路
刪除鏈表中等於給定值 val 的所有節點。舉例:
輸入: 1->2->6->3->4->5->6, val = 6
輸出: 1->2->3->4->5
1.1 迭代分析
爲了統一對不帶頭結點的單鏈表的結點的操作,額外使用啞結點。使用指針prev始終指向判斷是否刪除的結點的前驅,如果條件滿足,刪除prev->next(複習刪除鏈表結點操作)。
從鏈表裏刪除一個節點 node
的最常見方法是修改之前節點的 next
指針,使其指向之後的節點。
ListNode* removeElements(ListNode* head, int val) {
if (!head) { //空表,直接返回
return head;
}
ListNode *dummy = new ListNode(0); //使用啞結點統一操作
dummy->next = head;
ListNode *prev = dummy;
while (prev->next) {
if (prev->next->val == val) { //刪除值爲val的結點
ListNode *save = prev->next->next;
delete prev->next;
prev->next = save;
}
else {
prev = prev->next;
}
}
head = dummy->next;
delete dummy;
return head;
}
1.2 遞歸分析
遞歸的原則——大問題分解成小問題,小問題得到解決後,大問題也就解決了。應用遞歸的方法,我們來設計本遞歸函數。函數功能,刪除給定鏈表值爲val的全部結點,並且返回表頭指針。
- 如果爲空表,不進行任何操作,直接返回;
- 刪除首部爲head->next的鏈表值爲val的全部結點,暫存返回值;
- 如果head指向的結點值不爲val,將head和剩餘部分鏈接起來即可;如果爲val,刪除head後,將返回值賦值給head。
ListNode* removeElements(ListNode* head, int val) {
if (!head) { //空表直接返回
return head;
}
ListNode *save = removeElements(head->next, val);
if (head->val != val) {
head->next = save;
}
else {
delete head;
head = save;
}
return head;
}